かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

JavaScript (ES2015) アロー関数 省略した書き方とかのメモ

ES2015/ES6で追加されたアロー関数()=>{...}thisを拘束できるのがメインだと思っているのですが、色々と省略した書き方ができるようで、まだ不慣れなのでライブラリとか参考のコード見てる時に何だっけ?となりがちだったので省略した書き方のメモ。

アロー関数の基本形

(param1, param2) => {
 // ... 処理
}

関数名を付けて定義

const func = (param) => {
  // ... 処理
}

引数が1つのとき()を省略できる

(param) => { ... }

↓ 省略形

param => { ... }

値を返すだけの関数のときreturn{}を省略できる

(param) => { return val }

returnを省略

(param) => { val }

{}も省略

(param) => val
{}だけ省略はエラーになる
(param) => return val
// SyntaxError: Unexpected token return

オブジェクトを返す時は()で囲う

返すオブジェクトを()で囲わないと、オブジェクトの{}が関数のブロックと解釈される
ex: {cute: '星宮いちご'}というオブジェクトを返す関数

const foo = (param) => {cute: '星宮いちご'}
foo() // undefined

()で囲ってないとエラーにはならないがundefinedが返る
返すオブジェクトを()で囲む ↓

const foo = (param) => ({cute: '星宮いちご'})
foo() // {cute: '星宮いちご'}

↓ 下記と同様

const foo = (param) => {
  return {cute: '星宮いちご'}
}

正直{ return {...} }で良くない?って感じる…

const foo = (param) => { return {cute: '星宮いちご'} }

慣れの問題かもだけど、引数の()を省略は見づらい... 値を返すだけの関数を1行で書いて{}return省略するのは、返す値がオブジェクトや複雑な計算式だとやっぱ見通しが悪い気がしてます。
チームでの開発ならprettierとかフォーマッターを導入するか、書き方のルールを決めておかないと、省略形が入り乱れると結構混乱しそうって思いました。


これから学ぶ JavaScript

これから学ぶ JavaScript

JavaScript (ES2015) 分割代入でエラーになるトラップにはまる。

ECMAScript2015 (ES2015 / ES6)で追加された、配列やオブジェクトを分割して変数に代入できる分割代入で色々エラーになってハマったのでメモ。

分割代入 Destructuring assignment

分割代入 - JavaScript | MDN とは

// 配列
let [a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]

// オブジェクト
let {cute, cool, sexy, ...other} = {
  cute:   '星宮いちご',
  cool:   '霧矢あおい',
  pop:    '有栖川おとめ',
  sexy:   '紫吹蘭',
  legend: '神前美月'
};
console.log(cute);  // 星宮いちご
console.log(cool);  // 霧矢あおい
console.log(sexy);  // 紫吹蘭
console.log(other); // { pop: '有栖川おとめ', legend: '神前美月' }

こんなの。
配列は前から順番(インデックス順)に、オブジェクトは変数名と合致するプロパティの値が変数に代入される。

変数宣言外で分割代入をする際のトラップ

オブジェクトの分割代入を行う時、全体を()で囲ってないとエラーになる

変数宣言とオブジェクトの分割代入を別に行う場合は、分割代入の式全体を()で囲ってないとSyntaxError: Unexpected token

let a, b;
{a, b} = { a: 10, b: 20 };
console.log(a, b);
// {a, b} = { a: 10, b: 20 }
//       ^
// SyntaxError: Unexpected token =

↓ 分割代入全体を()で囲う

let a, b;
({a, b} = { a: 10, b: 20 });
console.log(a, b); // 10 20

分割代入の前の文にセミコロン;が無いとエラーになる場合がある

変数宣言だけだとエラーにならない

let a, b
[a, b] = [1, 2]
console.log(a, b) // 1, 2

変数宣言時に値を代入しているとReferenceError: X is not defined

let a = 1, b = 2
[a, b] = [b, a]
console.log(a, b)
// [a, b] = [b, a]
//    ^
// ReferenceError: b is not defined

↓ 前の文にセミコロン;があればエラーにならない

let a = 1, b = 2;
[a, b] = [b, a]
console.log(a, b) // 2 1

分割代入の直前に文末にセミコロン;がないconsole.log()のような文があるとTypeError

let a = 1, b = 2
console.log(a, b)
[a, b] = [b, a]
console.log(a, b)
// [a, b] = [b, a]
//        ^
// TypeError: Cannot set property '2' of undefined

↓ 分割代入直前の文末にセミコロン;をつければOK

let a = 1, b = 2
console.log(a, b); // 1 2
[a, b] = [b, a]
console.log(a, b)  // 2 1

別に前の文の文末でなくても、分割代入式の直前にセミコロンがあればOKっぽい

let a = 1, b = 2
console.log(a, b) // 1 2
;
[a, b] = [b, a]
console.log(a, b)  // 2 1

分割代入式の前に;を書いてしまってもOK

let a = 1, b = 2
console.log(a, b) // 1 2
;[a, b] = [b, a]
console.log(a, b)  // 2 1

分割代入の直前がブロックとか、セミコロン;で文の終わりが明示されていればエラーにならないっぽい?

let a = 1, b = 2
{} // function func() {} とかでもOK
[a, b] = [b, a]
console.log(a, b) // 2 1
オブジェクトでも同様。分割代入式の直前が;かブロックでないとエラー
let cute, cool
({cute, cool} = { cute: '星宮いちご', cool: '音城セイラ' })
console.log(cute, cool) // 星宮いちご, 音城セイラ

変数宣言だけなら文末にセミコロン;がなくてもエラーにならないが、
変数宣言時に初期値の代入があるとエラー (TypeError)

let cute = '星宮いちご', cool = '霧矢あおい'
({cute, cool} = { cute: '大空あかり', cool: '氷上スミレ' })
// ({cute, cool} = { cute: '大空あかり', cool: '氷上スミレ' })
// ^
// TypeError: "霧矢あおい" is not a function

↓ 代入している文章が終わってなく、分割代入の式が続いていて関数だと判断されているので、分割代入式の前に;をつけるか、ブロックになる式が入ればOK

let cute = '星宮いちご', cool = '霧矢あおい';
({cute, cool} = { cute: '大空あかり', cool: '氷上スミレ' })
console.log(cute, cool) // 大空あかり 氷上スミレ

とか

let cute = '星宮いちご', cool = '霧矢あおい', n = 5
while(n--) { console.log(n) }
({cute, cool} = { cute: '大空あかり', cool: '氷上スミレ' })
console.log(cute, cool) // 大空あかり 氷上スミレ

ブロック式があるとか

var cute = '星宮いちご', cool = '霧矢あおい'
;({cute, cool} = { cute: '大空あかり', cool: '氷上スミレ' })
console.log(cute, cool) // 大空あかり 氷上スミレ

分割代入式の先頭を;で始めるとか

分割代入の前に入る文がブロックでない場合は文末にセミコロン;が無いとエラーになる (TypeError)

function myFunc() { console.log('OKOKOK-') }
var sexy = '神前美月', pop = '夏樹みくる'
myFunc()
({sexy, pop} = { sexy: '風沢そら', pop: '冴草きい' })
// ({sexy, pop} = { sexy: '風沢そら', pop: '冴草きい' })
// ^
// TypeError: myFunc(...) is not a function

↓ 分割代入の直前にセミコロン;があればOK

function myFunc() { console.log('OKOKOK-') }
var sexy = '神前美月', pop = '夏樹みくる'
myFunc();
({sexy, pop} = { sexy: '風沢そら', pop: '冴草きい' })
console.log(sexy, pop) // 風沢そら 冴草きい

 

まとめ

変数宣言と同時でない分割代入は、下記パターンで文章が続いていると判断されてエラーになるようです。

  • オブジェクトの場合は分割代入の式全体を()で囲ってないとエラーになる
  • 分割代入式の直前が「変数宣言のみ」又は、セミコロン;かブロック{}でないとエラーになる

 
最近のJSのコードやESLintで、JSでセミコロン;は不要になったみたいな印象を勝手に受けてたのですが、基本的に必要な文末にはセミコロン付けるようにした方が良いんじゃないかなって思いました。
変数宣言と同時でない所で使う分割代入式はセミコロン;から始めること。としても良いかもですが、この方がLintとかに怒られたりで設定とかが面倒そうです…


[参考]

速習ECMAScript6: 次世代の標準JavaScriptを今すぐマスター! 速習シリーズ

速習ECMAScript6: 次世代の標準JavaScriptを今すぐマスター! 速習シリーズ

JavaScript (ES2015) スプレッド演算子のメモ

スプレッド演算子(Spread Operator) ... で使用
for of で回せるArray-like(イテラブル?)なオブジェクトを個々の値で展開できる
※配列での仕様はES2015/ES6で標準になっているが、オブジェクトでの仕様はまだドラフト (ECMAScript® 2019 Language Specification)

applyを利用して配列を展開して関数に渡して居たような処理をスプレッド演算子でシンプルに書くことができます。

function sum(x, y, z) {
  return x + y + z
}
const numbers = [1, 2, 3]
console.log( sum(...numbers) ) // 6
console.log( sum.apply(null, numbers) ) // 6

関数の引数をスプレッド演算子すれば、関数に渡される引数(arguments)を配列として扱うことができます。(argumentsとは違い配列なのでそのままmap,reduceなどの配列操作をすることができる)

function sum(...values) {
  // valuesは配列
  return values.reduce((sum, val) => {
    return sum + val
  }, 0)
}
console.log( sum(1, 2, 3) ) // 6

配列

配列のコピー

[...Array]で元の配列をコピーした新しい配列を作成

const arg1 = [1, 2, 3]
// 配列のコピー
const arg2 = [...arg1] // [1, 2, 3]
// コピーなので元の配列とは別
console.log(arg1 === arg2) // false
arg2[0] = 0
console.log(arg1, arg2) // [1, 2, 3] [0, 2, 3]

// 要素を追加した新しい配列を作成
const arg3 = ['a', ...arg1, 'b'] // ['a', 1, 2, 3, 'b']

配列の結合

concat()で結合していたのが簡単に書ける

const arg1 = [0, 1, 2]
const arg2 = [3, 4, 5]
var arg3 = [...arg1, ...arg2] // [0, 1, 2, 3, 4, 5]
// ↓ と同等
arg3 = arg1.concat(arg2) // [0, 1, 2, 3, 4, 5]

配列に要素を追加するpush(), unshift()の引数としても使える

var arg1 = [1, 2, 3]
var arg2 = ['a', 'b', 'c']
arg1.push(...arg2) // [ 0, 1, 2, 'a', 'b', 'c' ]
var arg1 = [1, 2, 3]
var arg2 = ['a', 'b', 'c']
arr1.unshift(...arr2) // [ 'a', 'b', 'c', 0, 1, 2 ]

オブジェクト

オブジェクトのコピー

{...Object}で新しいオブジェクトを作成

const obj1 = {a: 1, b: 2}
// オブジェクトのコピー
const obj2 = {...obj1} // { a: 1, b: 2 }
console.log(obj2 === obj1) // false
obj2.a = 0
console.log(obj1, obj2) // { a: 1, b: 2 } { a: 0, b: 2 }

// 要素を追加した新しいオブジェクトを作成
const arg3 = {z: 0, ...obj1, c: 3} // { z: 0, a: 1, b: 2, c: 3 }

オブジェクトのマージ

配列と同じ様に{...obj, ...obj}でオブジェクトをマージすることができます。

const obj1 = {a: 1, b: 2}
const obj2 = {c: 3, d: 4}
const mergedObj = {...obj1, ...obj2} // { a: 1, b: 2, c: 3, d: 4 }

オブジェクトに同じキーがある場合、最後に追加された値が残ります。

obj = {
  name: 'Mika',
  name: 'Aki',
  name: 'Mikko'
}
console.log(obj) // { name: 'Mikko' }

同じキーが有るオブジェクトのマージ

const obj1 = {a: 1, b: 2}
const obj2 = {a: 3, c: 4}
const mergedObj = {a: 0, ...obj1, ...obj2, c: 5} // { a: 3, b: 2, c: 5 }

スプレッド演算子の注意点

オブジェクト中に配列は展開できるが、配列にオブジェクトは展開できない

オブジェクトを[...obj]と配列中にコピーしようとするとエラーになります

const obj = {a:1, b:2}
const arg = [1, ...obj, 2]
// TypeError: obj is not iterable

逆に配列を{...array}でオブジェクト中にコピーすると、配列のインデックスをキーとしてオブジェクトにコピーされます。

const arg = ['foo', 'bar']
const obj1 = {a: 1, ...arg, b: 2}
// { '0': 'foo', '1': 'bar', a: 1, b: 2 }

// 配列のインデックスと同じキーが存在している場合は、マージされる
const obj2 = {0: 'a', ...arg, 2: 'b'}
// { '0': 'foo', '1': 'bar', '2': 'b' }

浅いコピー(shallow copy)

スプレッド演算子...でコピーした配列・オブジェクトは浅いコピー(shallow copy)なので、ネストされている配列・オブジェクトでは注意が必要

配列
const arg = [1, [2, 3], 4]
var copy = [...arg]
copy[1][0] = 'a'
console.log(arg) // [ 1, [ 'a', 3 ], 4 ]
オブジェクト
const obj = {
  a: {
    b: 1
  },
  c: 2
}
var copy = {...obj}
copy.a.b = 0
copy.a.d = 3
console.log(obj) // { a: { b: 0, d: 3 }, c: 2 }

ネストされている配列・オブジェクトを操作するともとの配列に影響を及ぼしてしまう

null, undefined

iterableではないnull,undefinedをスプレッド演算子で扱おうとした場合、配列([...null], [...undefined])はエラーになるが、オブジェクト({...null}, {...undefined})だとエラーにならない

[...null] // TypeError: null is not iterable
[...undefined] // TypeError: undefined is not iterable

{...null} // {}
{...undefined} // {}

スプレッド演算子の活用

文字列を配列にする

文字列(String)はArray-likeなオブジェクトなので...strで1文字づつ配列にすることができる。

const str = 'こんにちわJavaScript🎌'
console.log([...str])
// ['こ','ん','に','ち','わ','J','a','v','a','S','c','r','i','p','t','🎌' ]
const reversed = [...str].reverse().join('') // 🎌tpircSavaJわちにんこ

絵文字のようなものも1文字として扱われるっぽい。

配列・オブジェクトの分割

分割代入(Destructuring assignment) 構文は、配列から値を取り出して、あるいはオブジェクトからプロパティを取り出して別個の変数に代入することを可能にする JavaScript の式です。
出典: 分割代入 - JavaScript | MDN

配列
var [a, b, ...rest] = [1, 2, 3, 4, 5, 6, 7]
console.log(a, b, rest) // 1 2 [ 3, 4, 5, 6, 7 ]

スプレッド演算子は"残り"でしか指定できない

var [a, b, ...rest, c] = [1, 2, 3, 4, 5, 6, 7]
// => SyntaxError: Rest element must be last element
オブジェクト

オブジェクトの分割代入は変数名と同じキーの値が取得される

var {a, b} = {a:10, b:20, c:30}
console.log(a, b) // 10 20
var {c, d} = {foo:10, bar:20, baz:30}
console.log(c, d) // undefined undefined

スプレッド演算子で分割代入されたものはkey:valueを保持したオブジェクト形式になる

var {a, c, ...rest} = {a:1, b:2, c:3, d:4, e:5}
console.log(a, c, rest) // 1 3 { b: 2, d: 4, e: 5 }

↓みたいに関数の引数で...を使用しているのも分割代入なのかな?

function myFunc(x, y, ...other) { ... }

配列の重複を削除

一意な値を格納できるSetを利用すると配列から重複したデータを取り除いた配列を作成することができます。

const data = [0, 1, 2, 3.1, true, false, 1, "2", "", 3.1, null, undefined, NaN, false, NaN]
const dist = [...new Set(data)]
// [ 0, 1, 2, 3.1, true, false, '2', '', null, undefined, NaN ]

new Set()がSetオブジェクトを返したのを[]で配列化しているという認識で良いのでしょうか?

オブジェクトの初期値

{...null}, {...undefined}{}になることを利用するとオブジェクトのデフォルトオプションをつくったりできる

const createObj = (options) => {
  return {name: 'アシリパ', ...options}
}
obj1 = createObj() // {name: 'アシリパ'}
obj2 = createObj({name: '不死身の杉元'}) // {name: '不死身の杉元'}

ハックっぽいので見通しが良いかどうかは、ちょっと考えどころかもしれない

イテレーターがちゃんと理解できてないのでイテラブルとArray-likeの違いとかがイマイチまだあやふやなままです...


[参考]

JavaScript (ES2015) 文字列中に変数展開できるテンプレート構文のメモ

JavaScriptで変数を展開した文字列を作成する時、+で文字列連結をしていましたがES2015(ES6)からは``(バッククォート)で囲うテンプレート構文(Template literal)で書くことができるようです。
IEAndroidでは未対応なブラウザもあるようなので、WEBサイト制作とかの場合はまだバベる必要がありそうです。
ブラウザ実装状況: テンプレート文字列 - JavaScript | MDN

テンプレート構文(Template literal)による文字列中での変数展開

var val = "JavaScript"
// 今までのやり方
var str1 = "Hello " + val + "!" // => Hello JavaScript!
// テンプレート構文
var str2 = `Hello ${val}!` // => Hello JavaScript!

文字列中で変数を展開させるプレースホルダーは${...}の形式で記述します。

プレースホルダー内で計算

プレースホルダ${...}内では計算や関数を呼ぶこともできるようです。

var a = 3, b = 5
console.log( `a + b = ${a + b}, a * 2 + b = ${a * 2 + b}` )
// => a + b = 8, a * 2 + b = 11

function sub(a, b) {
  return a - b
}
console.log( `a - b = ${sub(a, b)}` )
// => a - b = -2

同期的なことはできない

function timer() {
  setTimeout(()=> {
    return 'timeout!'
  }, 100)
}
console.log( `set timer ... ${timer()}` )
// => set timer ... undefined

改行

テンプレート構文(Template literal)内では改行がそのまま改行として扱われる。(\nも使える)

var str1 = "Hello\nJavaScript"
// ↓
var str2 = `Hello
JavaScript`
var str3 = `Hello\nJavaScript`
console.log(str2)
// Hello
// JavaScript
console.log(str3)
// Hello
// JavaScript
コード上で改行だけさせたい時

見やすくするとかでコード上でだけ改行させたいような場合

var tag1 = "<div>"
+ "<p>Hello JavaScript</p>"
+ "</div>"
console.log(tag1)
// => <div><p>Hello JavaScript</p></div>

var tag2 = "<div>\
<p>Hello JavaScript</p>\
</div>"
console.log(tag2)
// => <div><p>Hello JavaScript</p></div>

テンプレート構文(Template literal)では改行はそのまま改行になってしまうので、改行前に\を付けて改行すればOK。(以前の方法と同じ)

var tag = `<div>\
<p>Hello JavaScript</p>\
</div>`
console.log(tag)
// => <div><p>Hello JavaScript</p></div>

エスケープ

\\nをそのまま表示したいような場合、テンプレート構文(Template literal)ではString.rawを使う。(\エスケープする今までどおりの方法でもOK)

var str1 = "Hello\\nJava\\Script"
// ↓
var str2 = String.raw`Hello\nJava\Script`
var str3 = `Hello\\nJava\\Script`
console.log(str1 === str2, str1 === str3, str2 === str3)
// => true true true
console.log(str2)
// => Hello\nJava\Script

String.raw内でもプレースホルダ${...}は展開される

var name = "アシリパ"
String.raw`こんにちわ\n${name}さん`
// => こんにちは\nアシリパさん

${...}をそのまま表示させたい場合はString.rawを使わずに\${...}又は$\{...}エスケープする

var name = "アシリパ"
`こんにちは\\n\${name}さん`
// => こんにちは\n${name}さん
`こんにちは\\n$\{name}さん`
// => こんにちは\n${name}さん

String.rawを使うと\${...}$\{...}\が出力されてしまう

var name = "アシリパ"
String.raw`こんにちは\n\${name}さん`
// => こんにちは\n\${name}さん
String.raw`こんにちは\n$\{name}さん`
// => こんにちは\n$\{name}さん

String.raw``のトラップ

テキストの最後に\を出力したい場合String.rawだと最後の`エスケープしていると判断されエラーになるので注意が必要

"Hello\\nJava\\Script\\"
// => Hello\nJava\Script\
`Hello\\nJava\\Script\\`
// => Hello\nJava\Script\
String.raw`Hello\nJava\Script\`
// => Error

String.rawを使って最後に\を出力するには\を文字列結合するか、プレースホルダーで追加すればOK

String.raw`Hello\nJava\Script` + "\\"
// => Hello\nJava\Script\
var suffix = "\\"
String.raw`Hello\nJava\Script${suffix}`
// => Hello\nJava\Script\

エスケープして表示したい時は今までどおりの\エスケープする方法の方が良さそうかも…

String.raw()

静的メソッドであるString.raw()は、文字列リテラルのための PythonrプレフィックスC#@プレフィックスのような template strings のタグ関数です。この関数は、template strings の生の文字列形式を取得するために使用されます。
出典: String.raw() - JavaScript | MDN

String.rawは関数なので、function``で関数が実行される。

テンプレート構文(Template literal)で実行された関数に渡される引数

テンプレート構文(Template literal)で渡される第一引数は文字列をプレースホルダーで分割したArray-likeな変更不可能なオブジェクト、第二引数以降はプレースホルダーに入る値。値は計算された状態で関数に渡されるっぽい。

var a = 5, b = 10
function tag(strings, ...values) {
  console.log(strings) // 変更不可オブジェクト
  console.log(values) // プレースホルダーの値
  return strings
}

var str1 = tag`Hello${a+b}Java${a-b}script`
// strings: [ 'Hello', 'Java', 'script' ]
// vales: [ 15, -5 ]

var str2 = tag`Hello${b-a}Java${a*b}script`
// strings: [ 'Hello', 'Java', 'script' ]
// values: [ 5, 50 ]

console.log(str1 === str2) // true
console.log(typeof(str1)) // 'object'

// 変更しようとするとエラーになる
str1[1] = 'World'
// => TypeError: Cannot assign to read only property
delete str1[2]
// => TypeError: Cannot delete property
str1.push('!')
// => TypeError: Cannot add property

公式を見るとクロージャーな関数を返すとか色々な使い方ができるっぽいけど、実際に使う場面がイマイチピンこない...
 

はてなブログJavaScriptいい感じにシンタックスハイライトされなくて辛い…


[参考]

マークダウンで`バッククォートをcodeで囲って書くTips

初めてのJavaScript 第3版 ―ES2015以降の最新ウェブ開発

初めてのJavaScript 第3版 ―ES2015以降の最新ウェブ開発

Mac Sublime Text 3 ESLint 導入メモ

ESLintをグローバルにインストール

$ npm install -g eslint

Sublime TextにSublimeLinterパッケージをインストール

  1. Sublime Textを起動しPackage Control(⌘+shift+P)を起動
  2. Installと入力しInstall Packageを選択
  3. SublimeLinterと入力しEnterを押してインストール

SublimeLinter-eslint パッケージをインストール

同じくSublime TextのPackage ControlからSublimeLinter-eslintと入力してインストール

SublimeLinter-eslint の設定を作成

Sublime Textの設定ファイルにLinterの設定を行わないとESLintがエディター上で動作しませんでした。

メニュー > Preferences > Package Settings > SublimeLinter > Setting を選択
設定ファイルが開くので、SublimeLinter Settings - User のコメントが有るUser設定に下記を記述

  1. eslint用の設定ファイルを作成
    eslint用の設定ファイルは中身はjson形式で勝手に作ってしまって構わないようです。(.eslintrc というファイルを作成しました)
  2. linters 内に eslint を作成し、args 内に1.で作成したeslint用の設定ファイルのパスを追加
  3. paths該当するOS内にeslintのあるパスを追加

eslintのパスは下記コマンドで見つけることができます。

$ which eslint
// SublimeLinter Settings - User
{
  "linters": {
    "eslint": {
      "@disable": false,
      "args": [
        "--config",
        "~/.eslintrc"
      ],
      "excludes": []
    },
  },
  "paths": {
    "linux": [],
    "osx": [
      "~/.nodebrew/current/bin"
    ],
    "windows": []
  }
}

これでSublime Textを再起動するとJSのファイルでESLintが動作しているかと思います。

エラーが出る場合

設定を保存して再起動したら下記のようなエラーが出る場合

Invalid settings in 'Packages/User/SublimeLinter.sublime-settings':
Additional properties are not allowed ('user' was unexpected)

SublimeLinter Ver.4から SublimeLinter Settings ファイルで"user"キーが廃止になったようで、Ver.3以前の設定ファイルなどを参考にすると、この"user"キーがあるのでこれが原因でエラーになってしまうようです。

// SublimeLinter Settings - User
{
  "user" {  // ← この囲いがSublimeLinter Ver.4からは不要
    "linters": {
      // 中略
    }
  }
}

eslint用の設定ファイル

作成したeslintの設定ファイル(~/.eslintrc)に何をエラーとして表示するかなどの設定を作成します。

{
  "extends": "eslint:recommended",
  "env": {
    "browser": true,
    "node": true,
    "es6": true
  },
  "globals": {
  },
  "rules": {
    "no-console": "warn",
    "no-var": "error"
    // ... 略
  }
}

作り込んでないのでざっくりとした理解ですが、大雑把に下記のようなイメージかと思います。

  • "extends": "eslint:recommended" ... ESLintの推奨設定を使用
  • "env" ... モジュールやライブラリで定義されている変数?
    • true (有効)
    • false (無効)
  • "globals" ... グローバル変数
    • true (書換え可)
    • false (書換え不可)
  • "rules" ... lintのルール
    • "off" (チェックしない)
    • "warn" (警告)
    • "error" (エラー)

Sublime Textの設定ファイルで読み込ませている.eslintrcはエディタ全体なので、どのプロジェクトにも適応されてしまうのでクリティカルな共通の設定に留め、詳細な設定は各プロジェクトごとに作成して読み込ませることができると良さそうです。

ESLintの設定読んである理解するのと、全体の設定(.eslintrc)とプロジェクトごとの設定をする方法を見つけて、次はコードフォーマッターのPrettierを入れたい。

Atomもっさりしてて結局使わなかったけど、そろそろVSCode試してみようかな…


[参考]

速習webpack 速習シリーズ

速習webpack 速習シリーズ