はじめに
自身のメモとして本記事ではESLintについての概要を記述します.ESLintの概要、Lintingの歴史、ESLintの全体像、そしてコマンドラインベースでSTEP by STEPでのESLintの利用についての解説を行います.別記事でReactの開発環境におけるESLint/Prettyer/stylelintの設定を記述いたします.
ESLintの概要
ESLintとはJavasScriptのためのlinterです.linterとはコードを静的に解析しコンパイラーで検出されない潜在的なバグを警告するプログラムです.linterを導入することでコーディングの品質を高めることが出来ます.静的にコードを解析する行為をLintingといいます.ESLintを利用することで、JavaScriptを静的に検証し、潜在的なバグを早期発見することが出来ます.特にJavaScritpは歴史的背景からバグを生みやすい言語であるためlinterで潜在的なバグを潰しておくことは重要です.
公式サイトにも記述されていますが、ESLintには3つの特徴があります.
①問題発見
ESLintはコードを静的に分析して、問題をすばやく見つけます.ESLintはほとんどのテキストエディタに組み込まれており、CI/CDパイプラインの一部としてESLintを実行できます.
②自動修正
ESLintが見つけた多くの問題は自動的に修正できます. ESLintの修正は構文に対応しているため、従来の検索と置換のアルゴリズムによって発生するエラーは発生しません.
③カスタマイズ
コードを前処理し、カスタムパーサーを使用して、ESLintの組み込みルールと一緒に機能する独自のルールを記述します.ESLintをカスタマイズして、プロジェクトに必要な方法で正確に機能させることができます.
2つ目の特徴として自動修正があげられていますが、Prettierのほうがコードのフォーマッターとしては強力なため、Prettierを併用してESLintは利用されます.
Linterの歴史
JavaScriptのLinterとしては2021年6月現在npmのパッケージダウンロード数から見てESLintが一強で、ESLintの利用がデファクトだという事がわかります.
JavaScriptのLinterの登場人物のざっくり説明です.
- JSLint(公式サイト、wiki)
- 最初のJavaScriptのlinterと言われています.(記事).
- 2002年にのDouglas Crockford(ダグラス・クロックフォード)が作成しました.
- Douglas Crockfordは「JavaScript: The Good Parts」の著者です.(wiki、Douglas Crockfordの書籍)
- JSHint(公式サイト、wiki)
- 2011年にAnton KovalyovがJSLintをフォークして作成しました.
- JSLintの問題として構文ルールはDouglas Crockfordの個人のコーディングスタイルの思想が強く反映されており、他の開発者が意見できない仕様になっているため、構文チェックのルールをオフにしたり設定変更ができない問題がありました.JSHintではこれを解消しました.(記事:Anton Kovalyov:Why I forked JSLint to JSHint)
- 設定ファイルを使用して構文チェックのルールのON/OFFの切り替えが可能です.
- 開発者コミュニティから支援されて開発された初めてのJavaScriptのlinterです.(記事:JSHint: A Community Driven Fork of JSLint)
- ESLint(公式サイト、wiki)
- 2013年にNicholas C. Zakasが作成しました.(記事、Nicolas C. Zakasの書籍)
- JSHintでは構文チェックのルールを拡張できない課題がありましたが、ESLintでは独自でルールを追加する可能にしこの問題を解消しました.独自ルールの追加以外にJSHintでも可能であった構文チェックのルールのON/OFFの切り替えも可能です.(記事:Understanding the Real Advantages of Using ESLint)
- 現在JavaScriptのlinterとして最も使われています.
- JSCS(公式サイト)
- 2014年にMarat Dulinが作成しました.
- 2016年にJSCSチームはESLintプロジェクトに合流し、JSCSのメンテナンスを中止しました.(記事:JSCS - End of Life、記事:Welcoming JSCS to ESLint)
- TSLint(公式サイト)
- 2016年にPalantir TechnologiesがESLintに相当するTypeScriptのlinterを作成しました.JSLint、JSHint、ESLint、JSCSはJavaScriptのlinterですが、TSLintはTypeScriptのlinterです.
- 2019年にTypeScriptの構文チェック機能を備えたESLintの利用をTSLint公式として推奨し、TSLintは非推奨となりました.
ESLintの仕組みのざっくり理解する
ここではESLintの仕組みをざっくり解説します.具体的にはルールとはなにか、Shareable Configs(共有設定)とは何かを解説します.
ルールによる構文チェック
ESLintではコーディングの記述の正しさをルールを用いて判定しています.ルールに準拠することで、統一感のあるコーディングが実現でき、コードの品質を高めることが出来ます.
たとえば、空のブロックの仕様を禁止するルールのno-emptyを見ましょう.no-emptyのルール上、下記の記述は正しくないため、ESLint上ではエラーがでます.
/*eslint no-empty: "error"*/
if (foo) {
}
while (foo) {
}
switch(foo) {
}
try {
doSomething();
}catch(ex) {
}finally {
}
no-emptyのルール上、下記の記述は正しいです.
/*eslint no-empty: "error"*/
if (foo) {
// empty
}
while (foo) {
/* empty */
}
try {
doSomething();
}catch (ex) {
// continue regardless of error
}
try {
doSomething();
}finally {
/* continue regardless of error */
}
別のルールも見てみましょう.semiはセミコロンを強制するルールです.semiのルール上、下記の記述は正しくないため、ESLint上ではエラーがでます.
/*eslint semi: "error"*/
var name = "ESLint"
object.method = function() {
// ...
}
semiのルール上、下記の記述は正しいです.
/*eslint semi: "error"*/
var name = "ESLint";
object.method = function() {
// ...
};
先程のno-emptyやsemiを含めて公式のESLintから膨大なルールが提供されています.ルール一覧はサイトで確認できます.これらルールを組み合わせて利用することで統一感のあるコーディングが実現でき、コードの品質を高めることが出来ます.
ルールはデフォルトで有効化されていないため、どのルールを有効化するかを利用者が指定する必要があります.また、ルールは独自でも作成可能なため、公式のESLintが提供するルールを使わなくてもlintingはできます.開発者が独自でルールを作成する方法について下記を参照ください.
Shareable Config(共有設定)
利用するルールを一つ一つ設定ファイルに記述するのは手間がかかります.ESLintではShareable Config(共有設定)という仕組みを使い、npmにパッケージを公開することで誰でも自分が設定しているルールを他のユーザに共有することができます.別の言い方をすると、誰かが作ってくれた設定を使うことで、自身でルールの設定をすることなく、統一感のあるコーディングができます.
npmjs.comにてeslint-configと検索すると、ESLintで利用可能なShareable Config(共有設定)を検索することができます.
良いコーディングを実現するためにAirbnbやGoogleなどがコーディングスタイルを提供しています.これらコーディングスタイルはESLintにてShareable Config(共有設定)として利用が可能です.ESLintで利用される代表的なコーディングスタイルは下記です.
- Airbnb JavaScript Style Guide(GitHub)
- 民泊サービスで知られるAirbnbが作成しているコーディングスタイルガイドです.ESLintで利用する際に候補としてあがる代表的なコーディングスタイルです.
- Google JavaScript Style Guide(公式ページ、GitHub、公式ページ和訳)
- Googleが提供するコーディングスタイルガイドです.こちらもESLintで利用する際に候補としてあがる代表的なコーディングスタイルです.
- JavaScript Standard Style Guide(公式ページ、GitHub)
- AirbnbやGoogle以外で代表的なコーディングスタイルガイドです.
npm trendsでパッケージダウンロード数で見るとAirbnbが人気なのがわかります.
スタイルガイドというのが適切かわからないですが、eslint-config-eslintにて公式のESLintが推奨するルールが提供されています.チェックマークが入っているのはESLintの公式が推奨しているルールです.これらルールの塊もShaerable Config(共有設定)として利用が可能です.
自動修正されるルール
ESLintの2つ目の特徴として自動修正がありましたが、すべてのルールが自動で修正されるわけではありません.ESLintの公式が提供するルールの中で、🔧(レンチ)のアイコンが記載されているルールに限り、自動でコードの修正が可能です.
動作確認
ESLintは自由度が高い構文チェックツールですので、手間を掛けずに挙動を確認できる環境(デモサイト)が公式から提供されています.ESLintには大量のルールがあるため、自身にあったルール探したり、ルールごとの挙動を確認するのに役立ちます.
さわって理解する
ここでは実際にESLintを使ってざっくりどういうことができるか理解したいと思います.
動作環境の確認
環境を確認します.
$ npm -v
7.18.1
$ node -v
v16.4.0
ESLintのインストール
yarn
を利用してeslintのパッケーをインストールします.
$ yarn add -D eslint
$ yarn eslint -v
v7.29.0
設定ファイルの確認
package.json
を確認します.
{
"devDependencies": {
"eslint": "^7.29.0"
}
}
.eslintrc.json
を確認します..eslintrc.json
はESLintの設定ファイルです.どのような共有設定を読み込むか、ルールのチューニングなどを行います.
{
"extends": ["eslint:recommended"],
"plugins": [],
"parserOptions": {},
"env": {},
"globals": {},
"rules": {}
}
記述されている内容だけ説明します.
-
"extends": ["eslint:recommended"]
- 先程インストールしたeslintに含まれるShareable Configを利用しています.
-
"eslint:recommended"
を読み込むことで、チェックマークが入っているルール一覧がlintingに適応されます.
チャレンジ1:global変数を理解する
ESLintの動作確認するconsole_example.js
を作成します.
console.log("hello world");
フォルダ構成は下記になります.
.
├── node_modules
├── package.json
├── console_example.js
├── yarn.lock
└── .eslintrc.json
実行するとメッセージが表示されます.
$ node console_example.js
hello world
ESLintをコマンドラインで利用します.
$ yarn eslint console_example.js
/Users/hayato94087/temp/console_example.js
1:1 error 'console' is not defined no-undef
✖ 1 problem (1 error, 0 warnings)
error Command failed with exit code 1.
下記がメッセージの読み方になります.
行数:列数 [error/warning] [エラー内容] [構文チェックに使用したルールの名称]
今回は1つのエラーが出ました.
-
no-undef
- 宣言されていない変数が使われているか検知するルールです.
-
console
の変数が認識されていないためエラーが出ています.
動作環境にあわせてESLintに認識すべきglobal変数を設定しておく必要があります.ESLintでは動作する環境ごとに定義されているglobal変数を.eslintrc.json
に設定します.env
で動作環境を指定することでglobal変数の指定が出来ます.指定可能な変数はESLintのサイトに記載があります.
{
"extends": ["eslint:recommended"],
"plugins": [],
"parserOptions": {},
- "env": {},
+ "env": {"browser": true},
"globals": {},
"rules": {}
}
設定内容の説明です.
-
browser:true
- ブラウザで動作するためbrowser
を有効化します.これによりwindow
やconsole
などのglobal変数をESLintが認識できるようになります.
ESLintをコマンドラインで利用します.何もエラーが出ないことを確認します.
$ yarn eslint console_example.js
チャレンジ2:エラーメッセージを理解し対処する
ESLintの動作確認するadd_example.js
を作成します.わざと2行目をb
ではなくc
の変数を記載しておきます.
function add(a,b) { return a+c }
var result = add(1,2)
console.log(result)
フォルダ構成は下記になります.
.
├── node_modules
├── package.json
├── add_example.js
├── console_example.js
├── yarn.lock
└── .eslintrc.json
実行してみる.実行時にランタイムエラーになる.
$ node add.js
/Users/hayato94087/temp/add_example.js:1
function add(a,b) { return a+c }
^
ReferenceError: c is not defined
at add (/Users/hayato94087/temp/add_example.js:1:30)
at Object.<anonymous> (/Users/hayato94087/temp/add_example.js:2:14)
at Module._compile (node:internal/modules/cjs/loader:1095:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1124:10)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:816:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:79:12)
at node:internal/main/run_main_module:17:47
ESLintをコマンドラインで利用します.
$ yarn eslint add.js
/Users/hayato94087/temp/add_example.js
1:16 error 'b' is defined but never used no-unused-vars
1:30 error 'c' is not defined no-undef
✖ 2 problems (2 errors, 0 warnings)
error Command failed with exit code 1.
今回は2つのエラーが出ました.
-
no-unused-vars
- 宣言されているが使われていない変数があるか検知するルールです.
-
b
は宣言されているが利用されていないためエラーを出しています.
-
no-undef
- 宣言されていない変数が使われているか検知するルールです.
-
c
は宣言されていないが使われているためエラーを出しています.
コードを修正します.
- function add(a,b) { return a+c }
+ function add(a,b) { return a+b }
var result = add(1,2)
console.log(result)
構文チェックを行います.
$ yarn eslint add_example.js
何もエラーが出ないことを確認します.
ランタイムエラーが無いことも確認します.
$ node add_example.js
3
ESLintを利用することでランタイムでしか検知できない問題点を事前に把握することができます.
チャレンジ3:ルールを追加して自分の構文チェック環境を構築する
ESLintの動作確認するcontrol_example.js
を作成します.
var foo =1
if ( foo) { foo++}
var bar = true
while ( bar) { bar=false }
if (foo) {
console.log("foo");
} else {
console.log("not ");
}
ここでは上記のような統一感の無いコードをESLintの自動修正機能を使って修正して下記のような形に変換します.
var foo =1
if (foo) {
foo++
}
var bar = true
while (bar) {
bar=false
}
if (foo) {
console.log("foo");
} else {
console.log("not ");
}
3つのルールを追加します.
- brace-styleを有効化し、{} の使い方に統一感をもたせます.
- indentを有効化し、インデントの幅を揃えます.
- space-in-parensを有効化し、() 内のスペースの利用を統一化します.
現状のESLintファイル(.eslintrc.json
)の設定を確認します.
{
"extends": ["eslint:recommended"],
"plugins": [],
"parserOptions": {},
"env": {"browser": true},
"globals": {},
"rules": {}
}
フォルダ構成は下記になります.
.
├── node_modules
├── package.json
├── add_example.js
├── console_example.js
├── control_example.js
├── yarn.lock
└── .eslintrc.json
構文チェックを行います.特にエラーは出ないです.
$ yarn eslint control_example.js
実行してみます.ランタイムエラーは起きません.
$ node control_example.js
foo
brace-styleの適応
brace-styleを有効化し、下記のような{}のスタイルを実現する.brace-style上、下記は正しいです.
/*eslint brace-style: "error"*/
if (foo) {
bar();
}
brace-style上、下記は正しくありません.
/*eslint brace-style: "error"*/
if (foo)
{
bar();
}
package.json
にbrace-styleのルールを追加します.
{
"extends": ["eslint:recommended"],
"plugins": [],
"parserOptions": {},
"env": {"browser": true},
"globals": {},
- "rules": {}
+ "rules": {
+ "brace-style": "error"
+ }
}
構文チェックを行います.
$ yarn eslint control_example.js
/Users/hayato94087/temp/control_example.js
2:12 error Statement inside of curly braces should be on next line brace-style
2:19 error Closing curly brace should be on the same line as opening curly brace or on the line after the previous block brace-style
5:15 error Statement inside of curly braces should be on next line brace-style
5:27 error Closing curly brace should be on the same line as opening curly brace or on the line after the previous block brace-style
✖ 4 problems (4 errors, 0 warnings)
4 errors and 0 warnings potentially fixable with the `--fix` option.
4つのエラーがでました.上のメッセージの中にpotentially fixable with the
--fix option
という文言があります.すでに紹介したとおり、ルールによっては自動修正してくれるルールも存在します.brace-styleは自動修正可能なルールなため、コマンドを使って自動修正します.
$ yarn eslint --fix control_example.js
自動修正されたソースコードは下記になります.
var foo =1
if ( foo) {
foo++
}
var bar = true
while ( bar) {
bar=false
}
if (foo) {
console.log("foo");
} else {
console.log("not ");
}
構文チェックでエラーが出ないことを確認しておきます.
$ yarn eslint control_example.js
indentの適応
indentを有効化し、インデントの幅を揃えます.indent上、下記は正しいです.
/*eslint indent: "error"*/
if (a) {
b=c;
function foo(d) {
e=f;
}
}
indent上、下記は正しくありません.
/*eslint indent: "error"*/
if (a) {
b=c;
function foo(d) {
e=f;
}
}
package.json
にindentのルールを追加します.
{
"extends": ["eslint:recommended"],
"plugins": [],
"parserOptions": {},
"env": {"browser": true},
"globals": {},
"rules": {
"brace-style": "error",
+ "indent": "error"
}
}
構文チェックを行います.
$ yarn eslint control_example.js
/Users/hayato94087/temp/control_example.js
3:1 error Expected indentation of 4 spaces but found 1 indent
8:1 error Expected indentation of 4 spaces but found 1 indent
14:1 error Expected indentation of 4 spaces but found 0 indent
✖ 3 problems (3 errors, 0 warnings)
3 errors and 0 warnings potentially fixable with the `--fix` option.
error Command failed with exit code 1.
3つのエラーがでました.indentは自動修正可能なルールなため、コマンドを使って自動修正します.
$ yarn eslint --fix control_example.js
自動修正されたソースコードは下記になります.
var foo =1
if ( foo) {
foo++
}
var bar = true
while ( bar) {
bar=false
}
if (foo) {
console.log("foo");
} else {
console.log("not ");
}
構文チェックでエラーが出ないことを確認しておきます.
$ yarn eslint control_example.js
space-in-parensの適応
space-in-parensを有効化し、、() 内のスペースの利用を統一化します.space-in-parens上、下記は正しいです.
/*eslint space-in-parens: "error"*/
foo( 'bar' );
space-in-parens上、下記は正しくありません.
/*eslint space-in-parens: "error"*/
foo('bar');
package.json
にindentのルールを追加します.
{
"extends": ["eslint:recommended"],
"plugins": [],
"parserOptions": {},
"env": {"browser": true},
"globals": {},
"rules": {
"brace-style": "error",
"indent": "error",
+ "space-in-parens": "error"
}
}
構文チェックを行います.
$ yarn eslint control_example.js
/Users/hayato94087/temp/control_example.js
2:5 error There should be no space after this paren space-in-parens
7:8 error There should be no space after this paren space-in-parens
✖ 2 problems (2 errors, 0 warnings)
2 errors and 0 warnings potentially fixable with the `--fix` option.
2つのエラーがでました.space-in-parensは自動修正可能なルールなため、コマンドを使って自動修正します.
$ yarn eslint --fix control_example.js
自動修正されたソースコードは下記になります.
var foo =1
if (foo) {
foo++
}
var bar = true
while (bar) {
bar=false
}
if (foo) {
console.log("foo");
} else {
console.log("not ");
}
構文チェックでエラーが出ないことを確認しておきます.
$ yarn eslint control_example.js
このようにyarn eslint —fix
のコマンドを実行することで自動修正を行うことができます.
チャレンジ4:npm-scriptsを利用しショートカット作成する
package.jsonファイル内にscriptsにコマンドを記載することで、いちいちコマンドを記載しなくても事項できる環境を作ります.package.json
にscriptsを追加します.yarn lint
で構文チェックのみ行い、yarn lint:fix
で構文チェックした後に自動修正を行えるようにします.
{
+ "scripts": {
+ "lint": "eslint *.js",
+ "lint:fix": "eslint *.js"
+ },
"devDependencies": {
"eslint": "^7.29.0"
}
}
実際に動かしてみます.
$ yarn lint
/Users/hayato94087/temp/add_example.js
1:19 error Statement inside of curly braces should be on next line brace-style
1:32 error Closing curly brace should be on the same line as opening curly brace or on the line after the previous block brace-style
✖ 2 problems (2 errors, 0 warnings)
2 errors and 0 warnings potentially fixable with the `--fix` option.
構文サンプル3で追加したbrace-styleに構文サンプル2のサンプルコード(add_example.js
)が準拠していないと怒られます.yarn lint:fix
で修正します.
$ yarn lint:fix
add_example.js
は修正されました.
function add(a,b) {
return a+b
}
var result = add(1,2)
console.log(result)
このように、ショートカットを利用することで、いちいちコマンド入力しなくても自動修正ができるものは修正可能になります.
念の為、現時点のpackage.json
を記載します.
{
"scripts": {
"lint": "eslint *.js",
"lint:fix": "eslint --fix *.js"
},
"devDependencies": {
"eslint": "^7.29.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.23.4"
}
}
下記は現時点の.eslintrc.json
です.
{
"extends": ["eslint:recommended"],
"plugins": [],
"parserOptions": {},
"env": {"browser": true},
"globals": {},
"rules": {
"brace-style": "error",
"indent": "error",
"space-in-parens": "error"
}
}
チャレンジ5:Airbnbのスタイルガイドを適応する
自分にあったルールを探して適応させていくのは一苦労です.Shareable Configsで説明しましたが、すでにAirbnbやGoogleがスタイルガイドを公開しているため、それをそのまま利用することで、品質の高いコーディングを実現できます.
今回はReactベースではないため、eslint-config-airbnb-baseのパケージをインストールします.依存関係を解消するためeslint-plugin-importもあわせてインストールします.
$ yarn add -D eslint-config-airbnb-base eslint-plugin-import
package.json
に追加されました
{
"scripts": {
"lint": "eslint *.js",
"lint:fix": "eslint --fix *.js"
},
"devDependencies": {
"eslint": "^7.29.0",
+ "eslint-config-airbnb-base": "^14.2.1",
+ "eslint-plugin-import": "^2.23.4"
}
}
.eslintrc.json
を修正しeslint-config-airbnb-baseをextendsに追記しています.参考までに、記述方法としてeslint-config-は省略が可能です.
{
"extends": ["airbnb-base"],
"plugins": [],
"parserOptions": {},
"env": {"browser": true},
"globals": {},
"rules": {
}
}
構文チェックします.
$ yarn lint
/Users/hayato94087/temp/add_example.js
1:15 error A space is required after ',' comma-spacing
2:1 error Expected indentation of 2 spaces but found 4 indent
2:13 error Operator '+' must be spaced space-infix-ops
2:15 error Trailing spaces not allowed no-trailing-spaces
2:15 error Missing semicolon semi
4:1 error All 'var' declarations must be at the top of the function scope vars-on-top
4:1 error Unexpected var, use let or const instead no-var
4:19 error A space is required after ',' comma-spacing
4:22 error Missing semicolon semi
5:1 warning Unexpected console statement no-console
5:20 error Newline required at end of file but not found eol-last
5:20 error Missing semicolon semi
/Users/hayato94087/temp/console_example.js
1:1 warning Unexpected console statement no-console
1:13 error Strings must use singlequote quotes
1:28 error Newline required at end of file but not found eol-last
/Users/hayato94087/temp/control_example.js
1:1 error Unexpected var, use let or const instead no-var
1:9 error Operator '=' must be spaced space-infix-ops
1:11 error Missing semicolon semi
3:1 error Expected indentation of 2 spaces but found 4 indent
3:5 error Unary operator '++' used no-plusplus
3:10 error Missing semicolon semi
5:1 error Trailing spaces not allowed no-trailing-spaces
6:1 error All 'var' declarations must be at the top of the function scope vars-on-top
6:1 error Unexpected var, use let or const instead no-var
6:15 error Missing semicolon semi
8:1 error Expected indentation of 2 spaces but found 4 indent
8:8 error Operator '=' must be spaced space-infix-ops
8:14 error Trailing spaces not allowed no-trailing-spaces
8:14 error Missing semicolon semi
11:11 error Trailing spaces not allowed no-trailing-spaces
12:1 error Expected indentation of 2 spaces but found 4 indent
12:5 warning Unexpected console statement no-console
12:17 error Strings must use singlequote quotes
14:1 error Expected indentation of 2 spaces but found 4 indent
14:5 warning Unexpected console statement no-console
14:17 error Strings must use singlequote quotes
14:25 error Trailing spaces not allowed no-trailing-spaces
15:2 error Newline required at end of file but not found eol-last
✖ 38 problems (34 errors, 4 warnings)
31 errors and 0 warnings potentially fixable with the `--fix` option.
error Command failed with exit code 1.
yarn lint:fix
で修正する前にそれぞれのファイルの内容を記述しておきます.
add_example.js
は下記です.
function add(a,b) {
return a+b
}
var result = add(1,2)
console.log(result)
console_example.js
は下記です.
console.log("hello_world");
control_example.js
は下記です.
var foo =1
if (foo) {
foo++
}
var bar = true
while (bar) {
bar=false
}
if (foo) {
console.log("foo");
} else {
console.log("not ");
}
はい、めちゃくちゃ怒られました.yarn lint:fix
で修正します.
$ yarn lint:fix
/Users/hayato94087/temp/add_example.js
5:1 warning Unexpected console statement no-console
/Users/hayato94087/temp/console_example.js
1:1 warning Unexpected console statement no-console
/Users/hayato94087/temp/control_example.js
3:3 error Unary operator '++' used no-plusplus
12:3 warning Unexpected console statement no-console
14:3 warning Unexpected console statement no-console
✖ 5 problems (1 error, 4 warnings)
error Command failed with exit code 1.
5件まで問題を減らすことができました.メッセージを見る限り、2種類のメッセージがあることがわかります.まずは、エラーになっているno-plusplusを修正します.
no-plusplusは空白の位置によって解釈が変わるため、++や—の利用を禁止するルールです.言葉だとわかりにくいのでこういう問題になります.
var i = 10;
var j = 20;
i ++
j
// i = 11, j = 20
var i = 10;
var j = 20;
i
++
j
// i = 10, j = 21
control_example.js
を下記の通り修正しました.
let foo = 1;
if (foo) {
- foo++;
+ foo += 1;
}
let bar = true;
while (bar) {
bar = false;
}
if (foo) {
console.log('foo');
} else {
console.log('not ');
}
これでエラーメッセージは解消できました.
$ yarn lint
/Users/hayato94087/temp/add_example.js
5:1 warning Unexpected console statement no-console
/Users/hayato94087/temp/console_example.js
1:1 warning Unexpected console statement no-console
/Users/hayato94087/temp/control_example.js
12:3 warning Unexpected console statement no-console
14:3 warning Unexpected console statement no-console
✖ 4 problems (0 errors, 4 warnings)
次は、4つのwarningの対処を行います.
JavaScriptはブラウザで利用するように設計されているため、デバッグで記述したと思われるconsoleの利用に対して警告文をno-consoleでは出しています.
次の行に対して特定のルールを無効化することができます.下記が特定のルールを無効化する記述方法です.
// eslint-disable-next-line [無効化したいルール名称]
[無効化したいルール名称]を記載しない場合はすべてのルールが無効化されます.
console_example.js
を修正しました.
let foo = 1;
if (foo) {
foo += 1;
}
let bar = true;
while (bar) {
bar = false;
}
if (foo) {
// eslint-disable-next-line no-console
console.log('foo');
} else {
// eslint-disable-next-line no-console
console.log('not ');
}
add_example.js
も同様に修正します.
function add(a, b) {
return a + b;
}
const result = add(1, 2);
// eslint-disable-next-line no-console
console.log(result);
console_example.js
も修正しますが、no-console
の記載を省略します.これはすべてのルールを無効化する意味があります.
// eslint-disable-next-line
console.log('hello_world');
これでerror/warningともに解消できました.
$ yarn lint
Airbnbのルールを適応することでいい感じに統一感のあるコーディングが実現できました!
チャレンジ6:エディター連携する
チャンレジ1〜5でESLintの基礎知識はだいぶ溜まったと思います.最後にエディターと連携させて、実用的な開発環境を整備したいと思います.
ESLintが連携可能なエディターの情報としては公式サイトに記述があります.今回はVisual Studio Code(以降VSCode)での設定を記述します.
VSCodeはサイトから取得してPCに設定してください.詳細は割愛します.
プロジェクトディレクトリに遷移し、code .
でVSCodeを開きます.
$ cd /Users/hayato94087/temp
$ code .
VSCodeが開いたら、左下の拡張機能(Extensions)をクリックしてください.
ESLintの拡張機能を検索します.「eslint」と入力して検索してください.検索結果を選択したら、「Install」をクリックして拡張機能のESLint(dbaeumer.vscode-eslint
)をインストールします.
動作確認のためif_example.js
のファイルを作成します.
var foo =1
if ( foo) { foo += 1}
フォルダ構成は下記になります.
.
├── node_modules
├── package.json
├── add_example.js
├── if_example.js
├── console_example.js
├── control_example.js
├── yarn.lock
└── .eslintrc.json
ESLintでのerrorは赤い波線で、warningは黄色い波線で表示されます.
VSCodeの設定を変更することで、ソースコードの保存時に自動修正できるようになります.command
+,
でSettings画面を開く、右上の赤枠をクリックし設定情報をJSONで編集する画面に遷移する.
settings.json
に下記を追加します.
{
// 保存時にコードアクションを実施
"editor.codeActionsOnSave": {
// ESLintの設定.VSCodeではESLintの自動修正をコードアクションとして実行
"source.fixAll.eslint": true,
},
// [editor.formatOnSave]と[source.fixAll.eslint]の設定が競合して正しく自動修正ができなくなることがあるため、保存時にフォーマットは無効化しておく
// https://qiita.com/musatarosu/items/a49ed897009ea272e24a
// https://sunday-morning.app/posts/2020-10-29-vscode-disable-editor-formatonsave
"editor.formatOnSave": false,
}
command
+s
でソースコードを保存し、保存時にESLintの自動修正を実行する.
ESLintをエディターと連携させることで、コーディングをしながらリアルタイムにlintingできる環境が構築でき、潜在的なバグの早期回収が可能になりました.
困ったことがあったら
ESLint 公式Discordに質問をすることでサポートを受けることができます.わからないことあったらここで聞きましょう.日本語のチャンネルもあります.
日本語の情報収集
公式の英語ドキュメントに抵抗がある方は下記でルールが日本語で解説されています.
- ESLintのエラールール。日本語ざっくり解説[可能性あるエラー編] - Qiita
- ESLintのエラールール。日本語ざっくり解説[ベストプラクティス編] - Qiita
- ESLintのエラールール。日本語ざっくり解説[スタイル編] - Qiita
- ESLintのエラールール。日本語ざっくり解説[ES6編] - Qiita
ESLintの最新の情報を取得する方法として
- @mysticateaがESLintの中の人で、ESLintでアップデートがあるとQiitaで情報発信してくれるウォッチするのがいいと思います.
最後に
本記事では、ESLintの概要、Lintingの歴史、ESLintの全体像、そしてコマンドラインベースでSTEP by STEPでESLintの仕組みについて解説しました.最後にエディターとの連携についても記述しました.別記事でReactの開発環境におけるESLint/Prettyer/stylelintの設定を記述いたします.
参考
- https://blog.natade.net/2018/11/03/web開発-歴史-用語-javascript-html5/
- https://blog.ojisan.io/eslint-prettier
- https://blog.ojisan.io/eslint-plugin-and-extend
- https://blog.ojisan.io/prettier-eslint-cli
- https://eslint.org/docs/developer-guide/shareable-configs
- https://garafu.blogspot.com/2017/02/eslint-rules-jp.html
- https://jtfal.com/docs/eslint/user-guide/configuring/
- https://qiita.com/howdy39/items/6e2c75861bc5a14b2acf
- https://qiita.com/khsk/items/0f200fc3a4a3542efa90
- https://qiita.com/M-ISO/items/f9097a75b362206c2a99
- https://qiita.com/mysticatea/items/dc35ced6bd5e782f50cd
- https://qiita.com/mysticatea/items/f523dab04a25f617c87d
- https://qiita.com/takeharu/items/dee0972e5f39bfd4d7c8
- https://www.tam-tam.co.jp/tipsnote/javascript/post11934.html
- https://www.tam-tam.co.jp/tipsnote/javascript/post9944.html