Hacktoberfest期間中ということで、Serverless Frameworkにプルリクエストを送っている。
途中、ESLintの動作で気になる部分があったのでメモしておく。
[ESLintとは]
ESLintはJavaScript用の静的解析ツールである。return文に続けてコードが書かれており到達不可能な箇所や、未使用の変数などプログラムのミスを検出してくれるだけでなく、それらを自動的に修正することもできる。
ミスとして検出可能なルールはデフォルトで250以上用意されており、JSXやNode.js専用のルールも存在する。
利用する場合にはプロジェクトのルートディレクトリでnpm i -D eslint
のコマンドを実行したのち、$(npm bin)/eslint --init
コマンドで設定ファイルを生成する。package.jsonに以下のようにscripts定義を追加し、npm run lint
コマンドを実行するとミスを検出することができる。
"scripts": { "lint": "eslint . --cache" }
[prefer-templateルール]
いくつか用意されているデフォルトのルールのうちの一つが「prefer-templateルール」である。端的に言えば、'foo'+bar
のようなコードがあった時に、JavaScriptの言語機能であるテンプレートリテラル(テンプレート文字列)を用いて`foo${bar}`
と記述しよう、というルールだ。
利用ルールに関する設定が記述されている.eslintrcファイルに以下のように追記するとprefer-templateルールを利用できる。
"rules": { "prefer-template": "error" }
テストのために以下のような内容をindex.jsファイルに追記する。
var name = 'bar' console.log('foo' + name)
この状態でnpm run lint
を実行すると
index.js 3:15 error Unexpected string concatenation prefer-template ✖ 1 problem (1 error, 0 warnings) 1 error and 0 warnings potentially fixable with the `--fix` option.
のようにエラーとなり、--fix
オプションをつけてコマンドを実行し、問題を自動的に修正するように伝えてくる。
[困ったことと回避策]
ここで、自動修正をすべく、package.jsonのスクリプトを以下のように修正する。
"scripts": { "lint": "eslint . --cache", "lint:fix": "npm run lint -- --fix", }
これで、npm run lint:fix
コマンドを実行すると自動的にソースコードが修正されるようになる。
実際にやってみると、以下のようになる。
【修正前】 console.log('foo' + name) 【修正後】 console.log(`foo${ name}`)
お分かりいただけるだろうか。なぜか${name}
ではなく、${ name}
と半角スペースが2つ混入してしまっている。
ルールの説明ページをみる限りでは、
【修正前】 var str = "Hello, " + name + "!"; 【修正後】 var str = `Hello, ${name}!`;
となるように読めるが、実際にはスペースが混入して以下のようになる。
【修正前】 var str = "Hello, " + name + "!"; 【修正後】 var str = `Hello, ${ name }!`;
サイトが正しくて、バグっているのかとも思ったが、テストコードをみる限りどうやら意図した動作であるらしい。ルールの実装箇所を読むと、どうやらこの辺りで+演算子の前後の空白を取り出してテンプレートリテラルの変数に付加しているらしかった。
実際、ローカルにインストールされたこのファイルに、以下のように.trim()を追加する修正を加えて、改めてnpm run lint:fix
コマンドを実行すると、不要なスペースのない意図した結果が得られた。
const textBeforePlus = getTextBetween(currentNode.left, plusSign).trim(); const textAfterPlus = getTextBetween(plusSign, currentNode.right).trim();
せっかくのHacktoberfestなのでプルリクエストを送ろうかとも考えたが、元の動きからかなり変わってしまうので、オプション化するなどした方がいいのだろうか……と迷っているうちに眠くなってしまったので、止めておいた。
Serverless Frameworkに提出中のプルリクエストにESLintを実行してこの問題が生じたが、結局手で不要なスペースを取り除いて回避することにした。
ESLint実行前のプログラムの+演算子の前後に半角スペースを入れず、'foo'+nameのように実装していれば、問題なく`foo${name}`に修正されるのだが、すでに`foo${ name}`と修正された後だったので、仕方なく手作業をした。
[まとめ]
これまでESLintあまり気にしていなかったけど、細かいところが気になってソースコードを読んだ。
細かいところを気にする前に、一度ちゃんとESLintの基本的な使い方学んで、いつかはESLintに修正される箇所のない高品質なJavaScriptプログラムを書きたい。