まず結論です。
上から順番に、
Lint確認のみ
Lint確認のみ(browserかnodeで使用)
Lint確認と優しめのFormat確認
Lint確認と厳しめのFormat確認
npx eslint --no-eslintrc --parser-options=ecmaVersion:latest sample.js
npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env browser,node sample.js
npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env es6,browser,node -c node_modules\eslint\conf\eslint-recommended.js sample.js
npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --env browser -c node_modules\eslint-config-airbnb-base\index.js sample.js
ちなみに、
ファイル名ではなく、
ディレクトリ名を指定すると、
ディレクトリ内の全てのJavaScriptファイルをLint確認出来ます。
カレントディレクトリを指定するのであれば.
例:npx eslint --no-eslintrc --parser-options=ecmaVersion:latest .
sample.js
以下機能等を含んだ、
以下コードで検証しています。
機能等
アロー関数
デフォルト引数
スプレッド構文
分割代入
残余引数
テンプレートリテラル
計算プロパティ名によるオブジェクト初期化子
Map
Set
WeakMap
WeakSet
Promise
Symbol
べき乗演算子(**)
Array.prototype.includes()
async function
await
String.prototype.padStart()
String.prototype.padEnd()
正規表現の肯定先読み
正規表現の否定先読み
正規表現の肯定後読み
正規表現の否定後読み
正規表現の名前付きグループ
String.prototype.trimStart()
String.prototype.trimEnd()
オプショナルキャッチバインディング
オプショナルチェーン(?.)
Null合体演算子(??)
論理和代入(||=)
論理積代入(&&=)
Null合体代入(??=)
正規表現のdフラグ
末尾のカンマ
コード
function func2015(n = 0, ...rest) {
console.log({}.toString.call(''));
console.log({}.toString.call([]));
console.log({}.toString.call({}));
console.log({}.toString.call(() => {}));
console.log(n);
console.log(n.toString().concat('', ...rest) * 1);
console.log(Array(5));
console.log(Array(5).fill());
console.log(Array(5).fill(0));
console.log([...Array(5).keys()]);
[...Array(5).keys()].forEach((i) => console.log(i));
const range1 = (start, stop, step = 1) => Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + i * step);
const range2 = (start, stop, step = 1) => Array(Math.trunc((stop - start) / step + 1)).fill().map((_, i) => start + i * step);
const range3 = (start, stop, step = 1) => [...Array(Math.trunc((stop - start) / step + 1)).keys()].map((i) => start + i * step);
console.log(range1(1, 10));
console.log(range2(1, 10));
console.log(range3(1, 10));
console.log(range1(1, 10, 2));
console.log(range2(1, 10, 2));
console.log(range3(1, 10, 2));
console.log([1, 4, 9].map((x) => x * 2));
console.log([12, 5, 8, 130, 44].filter((x) => x >= 10));
console.log([1, 2, 3, null, 5, undefined, false, 7].filter((x) => x));
console.log([0, 1, 2, 3].reduce((p, c) => p + c));
console.log([0, 1, 2, 3].reduce((p, c) => p + c, 0));
console.log([0, 1, 2, 3].reduce((p, c) => p + c, 10));
console.log([12, 54, 18, 130, 44].every((x) => x >= 20));
console.log([12, 54, 18, 130, 44].every((x) => x >= 10));
console.log([12, 5, 8, 1, 4].some((x) => x >= 20));
console.log([12, 5, 8, 1, 4].some((x) => x >= 10));
const [cat, dog] = ['neko', 'inu'];
console.log(`${cat}, ${dog}`);
console.log({ [cat]: 'nico' }.neko);
console.log(new Map([['cat', 'neko']]));
console.log(new Set(['cat', 'neko']));
console.log(new WeakMap());
console.log(new WeakSet());
console.log(new Promise(() => {}));
const res = new Promise((resolve) => {
resolve();
});
const rej = new Promise((resolve, reject) => {
reject();
});
res.then(() => {});
rej.then(() => {}).catch(() => {});
console.log(res);
console.log(rej);
console.log(Symbol('cat').toString());
console.log();
}
const func2016 = () => {
console.log(2 ** 4);
console.log([1, 2, 3].includes(3));
console.log();
};
const func2017 = async (...rest) => {
await new Promise((resolve) => {
setTimeout(resolve, 1000);
});
console.log('func2017.01---------------------------');
console.log(''.concat('', ...rest));
console.log((2017).toString().padStart(8, 0));
console.log((2017).toString().padEnd(8, '_'));
console.log('func2017.02---------------------------');
};
const func2018 = () => {
console.log('123456'.match(/123(?=456)/));
console.log('123456'.match(/123(?!456)/));
console.log('123456'.match(/(?<=123)456/));
console.log('123456'.match(/(?<!123)456/));
const s = 'I am a cat. Name is undefined.';
const r = s.match(/(?<c>cat).*(?<n>undef)/);
console.log(r);
console.log(r.groups.c);
console.log(r.groups.n);
console.log();
};
const func2019 = () => {
try {
console.log('try');
} catch {
console.log('catch');
}
console.log(' hello '.trimStart());
console.log(' world '.trimEnd());
console.log();
};
const func2020 = async () => {
await new Promise((resolve) => {
window.addEventListener('DOMContentLoaded', resolve);
});
console.log('func2020.01---------------------------');
console.log(document?.head);
console.log(document?.body);
console.log(document?.foot);
console.log(document?.foot?.heel);
console.log(document?.head && 'find head');
console.log(document?.body && 'find body');
console.log(document?.foot && 'find foot');
console.log(document?.foot?.heel && 'find heel');
console.log(document?.head || 'not found head');
console.log(document?.body || 'not found body');
console.log(document?.foot || 'not found foot');
console.log(document?.foot?.heel || 'not found heel');
console.log(document?.head ?? 'not found head');
console.log(document?.body ?? 'not found body');
console.log(document?.foot ?? 'not found foot');
console.log(document?.foot?.heel ?? 'not found heel');
console.log('func2020.02---------------------------');
};
const func2021 = () => {
let x = 0;
let y = 1;
let z;
console.log((x ||= 'Logical OR assignment'));
console.log((y &&= 'Logical AND assignment'));
console.log((z ??= 'Logical nullish assignment'));
console.log();
};
const func2022 = () => {
const s = 'I am a cat. Name is undefined.';
const r = s.match(/(?<c>cat).*(?<n>undef)/d);
console.log(r);
console.log(r[0]);
console.log(r[1]);
console.log(r[2]);
console.log(r.indices[0]);
console.log(r.indices[1]);
console.log(r.indices[2]);
console.log(r.groups.c);
console.log(r.groups.n);
console.log(r.indices.groups.c);
console.log(r.indices.groups.n);
console.log();
};
// main
func2015(2, 0, 1, 5);
func2016();
func2017(
'T',
'r',
'a',
'i',
'l',
'i',
'n',
'g',
' ',
'c',
'o',
'm',
'm',
'a',
's',
' ',
'i',
'n',
' ',
'f',
'u',
'n',
'c',
't',
'i',
'o',
'n',
's',
);
func2018();
func2019();
func2020();
func2021();
func2022();
<!doctype html>
<html>
<head>
<script src="sample.js"></script>
</head>
<body>
</body>
</html>
install
まずは、
npm i -D eslint
npm i -D eslint-config-airbnb-base
します。
iはinstallのエイリアスで、
-Dは--save-devのエイリアスなので、
npm install --save-dev eslint
npm install --save-dev eslint-config-airbnb-base
と同じです。
※Node.js(およびnpm)はインストールされているものとします。
https://www.npmjs.com/package/eslint
https://www.npmjs.com/package/eslint-config-airbnb-base
https://docs.npmjs.com/cli/commands/npm-install
npx eslint sample.js
npx eslint sample.js
上記を実行します。しかし、
設定ファイルが見つからんよ、
と言われます。
ということで、
npx eslint --no-eslintrc sample.js
npx eslint --no-eslintrc sample.js
上記を実行します。しかし、
デフォルト引数の部分でerrorになってしまいます。
ESLintの標準はES5相当のようなのです。
ということで、
ECMAScript
npx eslint --no-eslintrc --env es6 sample.js
上記を実行します。しかし、
べき乗演算子(**)
などを解析出来ないようです。
ということで、
npx eslint --no-eslintrc --env es2016 sample.js
上記を実行します。しかし、
async function
などを解析出来ないようです。
ということで、
npx eslint --no-eslintrc --env es2017 sample.js
npx eslint --no-eslintrc --env es2018 sample.js
npx eslint --no-eslintrc --env es2019 sample.js
npx eslint --no-eslintrc --env es2020 sample.js
npx eslint --no-eslintrc --env es2021 sample.js
上記を実行します。しかし、
なんだかんだ解析出来ないところがあり、
errorになってしまいます。
ということで、
npx eslint --no-eslintrc --env es2022 sample.js
上記を実行して、
ようやくerrorなく解析完了出来ます。
しかし、
ECMAScriptのバージョンが上がるごとに、
コマンドの引数を変更しなければならないのは面倒です。
ということで、
ecmaVersion:latest
npx eslint --no-eslintrc --parser-options=ecmaVersion:latest sample.js
とします。
これで最新のECMAScriptで解析してくれます。
ところで、
--env
と--parser-options=ecmaVersion
の違いは何でしょうか?
ESLint Language Options # Specifying Parser Options
上記に記載があり、
--env es6
はES6のグローバル変数を有効にする、
--parser-options=ecmaVersion:6
はES6のグローバル変数を有効にしない、
とのことです。
しかし、この段階では謎です。何故なら、
npx eslint --no-eslintrc --parser-options=ecmaVersion:latest sample.js
何もerrorが出ないのです...
--env
未指定なのに、
ES2015(ES6)で追加されたMap,Set,WeakMap,WeakSet,Promise,Symbolが、
問題なく解析出来ています。
ともかく進めます。
npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module sample.js
npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env browser,node sample.js
--parser-options=sourceType:module
一応上記オプションを追加しておきます。
--env browser,node
一応上記オプションも追加しておきます。
ブラウザとNodeのグローバルオブジェクトが認識出来るようになります。
ここまでで基本的な構文解析が可能です。
ESLintの推奨設定
node_modules\eslint\conf\eslint-recommended.js
ESLintの推奨設定があるようなので利用してみます。
npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env browser,node -c node_modules\eslint\conf\eslint-recommended.js sample.js
上記を実行します。しかし、
ES2015(ES6)で追加されたMap,Set,WeakMap,WeakSet,Promise,Symbolで、
何それおいしいの?と言われます。
どうも設定ファイルを読み込むとESlintの初期設定も無設定にされてしまうようです。
--env es6
を追加します。
ということで、
npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env es6,browser,node -c node_modules\eslint\conf\eslint-recommended.js sample.js
上記を実行します。
問題なく解析出来ました。
ESLintの全部設定
node_modules\eslint\conf\eslint-all.js
ESLintの全部設定があるようなので利用してみます。
npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env es6,browser,node -c node_modules\eslint\conf\eslint-all.js sample.js
滅茶苦茶errorが出ます。
なかには、
Comments should not begin with a lowercase character
コメントは小文字で始めるべきではありません。
いや、こまか!!
ということで、
eslint-config-airbnb-base
airbnbです。
ESLintは設定が多岐に渡るので丁度良い設定を誰か作ってくれい、
ということで、
eslint-config-airbnb-base
eslint-config-airbnb
eslint-config-google
eslint-config-standard
です。
eslint-config-airbnb-baseと
eslint-config-airbnbの違いはreactなどの有無とのことです。
airbnbとgoogleとstandardの三種類が有名なようですが、
https://npmtrends.com/eslint-config-airbnb-vs-eslint-config-airbnb-base-vs-eslint-config-google-vs-eslint-config-standard
上記を見ると2022年12月現在、
eslint-config-airbnb-base
が一番使用されているようなので、
冒頭でインストールしています。
ということで、
npx eslint --no-eslintrc -c node_modules\eslint-config-airbnb-base\index.js sample.js
上記を実行します。
optional catch bindingでerrorが出ます...
eslint-config-airbnb-baseの設定を見ると、
ecmaVersion:2018
となっています...
ecmaVersion:latest
にします。あと
--env browser
を追加しておきます。
ということで、
npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --env browser -c node_modules\eslint-config-airbnb-base\index.js sample.js
です。
これでeslintrcを使用せず、
JavaScriptをairbnbのconfigでESLint出来ました。
おまけ
https://www.npmjs.com/package/prettier
PrettierはJavascriptなどのFormatterです。
https://npmtrends.com/eslint-config-airbnb-vs-eslint-config-airbnb-base-vs-eslint-config-google-vs-eslint-config-standard-vs-prettier
PrettierはJavascript以外のFormatterでもあるので、
単純比較では比較出来ないかもしれませんが、
上記を見るととても使われているようです。
なので、
npm i -D prettier
します。
npx prettier --print-width 100 --single-quote --trailing-comma all -c sample.js
とすると、
airbnbと構文解釈が、
大凡一緒になりますが、
全く一緒ではないので、
うまいこと書く必要がありますね...
WindowsのCLIのテスト用バッチファイル
@pause
echo npx eslint sample.js
call npx eslint sample.js
echo npx eslint --no-eslintrc sample.js
call npx eslint --no-eslintrc sample.js
echo npx eslint --no-eslintrc --env es6 sample.js
call npx eslint --no-eslintrc --env es6 sample.js
echo npx eslint --no-eslintrc --env es2016 sample.js
call npx eslint --no-eslintrc --env es2016 sample.js
echo npx eslint --no-eslintrc --env es2017 sample.js
call npx eslint --no-eslintrc --env es2017 sample.js
echo npx eslint --no-eslintrc --env es2018 sample.js
call npx eslint --no-eslintrc --env es2018 sample.js
echo npx eslint --no-eslintrc --env es2019 sample.js
call npx eslint --no-eslintrc --env es2019 sample.js
echo npx eslint --no-eslintrc --env es2020 sample.js
call npx eslint --no-eslintrc --env es2020 sample.js
echo npx eslint --no-eslintrc --env es2021 sample.js
call npx eslint --no-eslintrc --env es2021 sample.js
echo npx eslint --no-eslintrc --env es2022 sample.js
call npx eslint --no-eslintrc --env es2022 sample.js
echo npx eslint --no-eslintrc --parser-options=ecmaVersion:latest sample.js
call npx eslint --no-eslintrc --parser-options=ecmaVersion:latest sample.js
echo npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module sample.js
call npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module sample.js
echo npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env browser,node,webextensions sample.js
call npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env browser,node,webextensions sample.js
@pause
echo npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env browser,node,webextensions -c node_modules\eslint\conf\eslint-recommended.js sample.js
call npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env browser,node,webextensions -c node_modules\eslint\conf\eslint-recommended.js sample.js
echo npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env es6,browser,node,webextensions -c node_modules\eslint\conf\eslint-recommended.js sample.js
call npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env es6,browser,node,webextensions -c node_modules\eslint\conf\eslint-recommended.js sample.js
echo npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env es6,browser,node,webextensions -c node_modules\eslint\conf\eslint-all.js sample.js
call npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --parser-options=sourceType:module --env es6,browser,node,webextensions -c node_modules\eslint\conf\eslint-all.js sample.js
@pause
@rem after install eslint-config-airbnb-base
echo npx eslint --no-eslintrc -c node_modules\eslint-config-airbnb-base\index.js sample.js
call npx eslint --no-eslintrc -c node_modules\eslint-config-airbnb-base\index.js sample.js
echo npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --env browser,webextensions -c node_modules\eslint-config-airbnb-base\index.js sample.js
call npx eslint --no-eslintrc --parser-options=ecmaVersion:latest --env browser,webextensions -c node_modules\eslint-config-airbnb-base\index.js sample.js
@pause
@rem after install prettier
echo npx prettier --print-width 100 --single-quote --trailing-comma all -c sample.js
call npx prettier --print-width 100 --single-quote --trailing-comma all -c sample.js
@pause
あとがき
ノンプログラマーの素人が記述をしたコードです。
狭い利用範囲と少ない利用頻度での確認ですので、
記載内容に間違いや勘違いがあるかもしれません。
上記内容を参照の際は自己責任でお願い致します。
参考
ESLint Documentation
https://eslint.org/docs/latest/
https://eslint.org/docs/latest/user-guide/
https://eslint.org/docs/latest/user-guide/configuring/configuration-files
https://eslint.org/docs/latest/user-guide/configuring/configuration-files#using-eslintrecommended
https://eslint.org/docs/latest/user-guide/configuring/configuration-files#using-eslintall
https://eslint.org/docs/latest/user-guide/configuring/language-options
https://eslint.org/docs/latest/user-guide/configuring/language-options#specifying-parser-options
https://eslint.org/docs/latest/user-guide/command-line-interface
みどりのさるのエンジニア ESLintをちゃんと理解する
https://t-yng.jp/post/understand-eslint
とほほのJavaScript
https://www.tohoho-web.com/js/
https://www.tohoho-web.com/js/what.htm
caniuse ECMAScript
https://caniuse.com/?search=ECMAScript
https://caniuse.com/?search=ECMAScript-20
ECMAScript compatibility table
https://kangax.github.io/compat-table/es6/
https://kangax.github.io/compat-table/es2016plus/