1
1
# ESLint
2
2
3
- > この文章は[ ESLint] ( http://eslint.org/ " ESLint ") 1.3.0を元に書かれています 。
3
+ > この文章は[ ESLint] ( http://eslint.org/ " ESLint ") v7.8.1を元に書かれています 。
4
4
5
5
[ ESLint] ( http://eslint.org/ " ESLint ") はJavaScriptのコードをJavaScriptで書かれたルールによって検証するLintツールです。
6
6
7
7
大まかな動作としては、検証したいJavaScriptのコードをパースしてできたAST(抽象構文木)をルールで検証し、エラーや警告を出力します。
8
8
9
9
このルールがプラグインとして書くことができ、ESLintのすべてのルールはプラグインとして実装されています。
10
10
11
- > The pluggable linting utility for JavaScript and JSX
11
+ > Find and fix problems in your JavaScript code
12
12
13
13
ESLintサイト上には、上記のように書かれていることからもわかりますが、プラグインに重きを置いた設計となっています。
14
14
15
15
今回はESLintのプラグインアーキテクチャがどうなっているかを見て行きましょう。
16
16
17
17
## どう書ける?
18
18
19
- ESLintでは` .eslintrc ` という設定ファイルに利用するルールの設定をして使うため、
20
- 実行方法についてはドキュメントを参照してください。
19
+ ESLintでは` .eslintrc ` という設定ファイルに利用するルールを設定して利用します。
20
+ そのため、 実行方法についてはドキュメントを参照してください。
21
21
22
22
- [ Documentation - ESLint - Pluggable JavaScript linter] ( http://eslint.org/docs/user-guide/configuring " Documentation - ESLint - Pluggable JavaScript linter ")
23
23
24
- ESLintにおけるルールとは、次のような関数をexportしたモジュールです 。
25
- 関数には ` context ` オブジェクトが渡されるので、それに対して1つのオブジェクトを返すようにします。
24
+ ESLintにおけるルールとは、次のような ` create ` メソッドをもつオブジェクトをexportしたモジュールです 。
25
+ ` create ` メソッドには ` context ` オブジェクトが渡されるので、それに対して1つのオブジェクトを返すようにします。
26
26
27
27
[ import, no-console.js] ( ../../src/ESLint/no-console.js )
28
28
@@ -75,8 +75,8 @@ console.log("Hello!");
75
75
76
76
ESLintではこのASTを使って、[ no-console.js] ( #no-console.js ) のように` console.log ` などがコードに残ってないかなどをルールを元にチェックできます。
77
77
78
- ルールをどう書けるかという話に戻すと、` context ` というオブジェクトはただのユーティリティ関数と考えて問題ありません 。
79
- ルールの本体は関数が ` return ` してるメソッドをもったオブジェクトです。
78
+ ルールをどう書けるかという話に戻すと、` context ` というオブジェクトはただのユーティリティ関数の集合と考えて問題ありません 。
79
+ ルールの本体は ` create ` メソッドが ` return ` してるメソッドをもったオブジェクトです。
80
80
81
81
このオブジェクトはNodeのtypeをキーとしたメソッドを持っています。
82
82
そして、ASTを探索しながら「` "MemberExpression" ` typeのNodeに到達した」と登録したルールに対して通知(メソッド呼び出し)を繰り返しています。
@@ -101,7 +101,7 @@ ESLintではこのASTを使って、[no-console.js](#no-console.js)のように`
101
101
[ no-console.js] ( #no-console.js ) のルールを見ると` MemberExpression ` typeのNodeが ` node.object.name === "console" ` となった場合に、
102
102
` console ` が残ってると判断してエラーレポートすると読めてくると思います。
103
103
104
- ASTの探索がイメージしにくい場合は次のルールで探索の動作を見てみると分かりやすいかもしれません 。
104
+ ASTの探索がイメージしにくい場合は、次のルールで探索の動作を見てみると分かりやすいかもしれません 。
105
105
106
106
- [ azu.github.io/visualize_estraverse/] ( http://azu.github.io/visualize_estraverse/ " visualize estraverse step ")
107
107
@@ -120,7 +120,7 @@ debug("Hello");
120
120
121
121
その他、ESLintのルールの書き方についてはドキュメントや次の記事を見てみるといいでしょう。
122
122
123
- - [ Documentation - ESLint - Pluggable JavaScript linter] ( http ://eslint.org/docs/developer-guide/working-with-rules " Documentation - ESLint - Pluggable JavaScript linter " )
123
+ - [ Working with Rules - ESLint - Pluggable JavaScript linter] ( https ://eslint.org/docs/developer-guide/working-with-rules)
124
124
- [ コードのバグはコードで見つけよう!|サイバーエージェント 公式エンジニアブログ] ( http://ameblo.jp/principia-ca/entry-11837554210.html " コードのバグはコードで見つけよう!|サイバーエージェント 公式エンジニアブログ ")
125
125
126
126
## どのような仕組み?
@@ -148,22 +148,22 @@ import {EventEmitter} from "events";
148
148
149
149
function lint (code ){
150
150
// コードをパースしてASTにする
151
- let ast = parse (code);
151
+ const ast = parse (code);
152
152
// イベントの登録場所
153
- let emitter = new EventEmitter ();
154
- let results = [];
153
+ const emitter = new EventEmitter ();
154
+ const results = [];
155
155
emitter .on (" report" , message => {
156
156
// 3. のためのreportされた内容を集める
157
157
results .push (message);
158
158
});
159
159
// 利用するルール一覧
160
- let ruleList = getAllRules ();
160
+ const ruleList = getAllRules ();
161
161
// 1. ルール毎に使っている`Node.type`をイベント登録する
162
162
ruleList .forEach (rule => {
163
163
// それぞれのルールに定義されているメソッド一覧を取得
164
164
// e.g) MemberExpression(node){}
165
165
// => {"MemberExpression" : function(node){}, ... } というオブジェクト
166
- let methodObject = getDefinedMethod (rule);
166
+ const methodObject = getDefinedMethod (rule);
167
167
Object .keys (methodObject).forEach (nodeType => {
168
168
emitter .on (nodeType, methodList[nodeType]);
169
169
});
@@ -245,27 +245,31 @@ add(1, 3);
245
245
このプラグインアーキテクチャはPub/Subパターンを上手く使い、
246
246
ESLintのように与えられたコードを読み取ってチェックするような使い方に向いています。
247
247
248
- つまり、read -onlyなプラグインアーキテクチャとしてはパフォーマンスも期待できると思います。
248
+ つまり、複数のルールで同時にLintをするというread -onlyなプラグインアーキテクチャとしてはパフォーマンスも期待できると思います。
249
249
250
- また、ルールは ` context ` という与えられたものだけを使うようになっているため 、ルールと本体が密結合にはなりにくいです。
251
- そのため` context ` に何を与えるかを決めることで、ルールが行える範囲を制御しやすいといえます 。
250
+ また、ルールは ` context ` オブジェクトという与えられたものだけを使うようになっているため 、ルールと本体が密結合にはなりにくいです。
251
+ そのため` context ` に何を与えるかを決めることで、ルールができる範囲を制御しやすいといえます 。
252
252
253
253
## どのような用途に向いていない?
254
254
255
255
逆に与えられたコード(AST)を書き換える場合には、
256
- ルールを同時に処理を行うためルール間で競合するような変更がある場合に破綻してしまいます 。
256
+ ルールを同時に処理を行うためルール間で競合するような変更がある場合に上手く整合性を保つ必要があります 。
257
257
258
- そのため、この仕組みに加えてもう1つ抽象レイヤーを設けないと対応は難しいです。
258
+ たとえば、あるルールが書き換えるとコードの位置に更新がかかるため、その後のルールはコードの位置更新の影響を受けます。
259
+ そのため、コードの書き換えをするにはこの仕組みに加えて、もう1つ抽象レイヤーを設けないと対応は難しいです。
259
260
260
- つまり、read-writeなプラグインアーキテクチャとしては単純にこのパターンだけでは難しい部分が出てくると思います 。
261
+ つまり、read-writeなプラグインアーキテクチャとしては、このパターンだけでは難しい部分が出てくると思います 。
261
262
262
- > ** NOTE** ESLint 2.0でautofixing、つまり書き換えの機能の導入が予定されています。
263
- > これはルールからの書き換えのコマンドを` SourceCode ` というオブジェクトに集約して、最後に実際の書き換えを行うという抽象レイヤーを設けています。
263
+ > ** NOTE** ESLint 2.0からautofix、つまり書き換えの機能の導入が導入されています
264
+ > ESLintでは、各ルールが書き換える位置や文字列を` fixer ` オブジェクトという形で報告し、ESLint本体がルールの順番を考慮して最後に実際の書き換えを行うという抽象レイヤーを設けています。
265
+ > これは[ Command パターン] ( https://ja.wikipedia.org/wiki/Command_%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3 ) を利用してトランザクション的なふるまいを実現しています。
264
266
> - [ Implement autofixing · Issue #3134 · eslint/eslint] ( https://github.com/eslint/eslint/issues/3134 " Implement autofixing · Issue #3134 · eslint/eslint ")
265
267
266
268
## この仕組みを使っているもの
267
269
268
- - [ azu/textlint] ( https://github.com/azu/textlint " azu/textlint ")
270
+ - [ stylelint] ( https://github.com/stylelint/stylelint )
271
+ - CSSのLintするツール
272
+ - [ textlint] ( https://github.com/textlint/textlint )
269
273
- テキストやMarkdownをパースしてASTにしてLintするツール
270
274
271
275
## エコシステム
@@ -293,7 +297,7 @@ ESLint公式の設定として`eslint:recommended`が用意されています。
293
297
設定なしで使えると一番楽ですが、設定なしだと誰でも使えるツールにするのは難しいです。
294
298
それを解消するために柔軟な設定のしくみと設定を共有しやすくしています。
295
299
296
- これは_The pluggable linting utility_を表現している仕組みといえるかもしれません 。
300
+ これは_Pluggable JavaScript linter_を表現している仕組みといえるかもしれません 。
297
301
298
302
## まとめ
299
303
0 commit comments