はじめに
自身が開発しているプロジェクト内で少し議論になった事もあり、importの自動整形についてはどうなのか?考えてみた。
(プロジェクトや個人の考え方に結局よると事だが)なんとなく結論としては、ESLint・Prettierの構成を取っているなら、スタイルの修正をESLintで行わせる事になるimportの自動整形は「なし」になるだろうなと思う。
以下では、ESLint・Prettierの構成の場合に、なぜimportの自動整形が「なし」になりそうか?についてみていきつつ、ESLintの静的解析とPrettierのコード整形を分離する方法についても見ていく。
おまけとして、「なし」といったもののやりたいという需要もあると思われるので、importの自動整形を行う方法についても取り上げた。
importの自動整形はできるけど、ESLint × Prettierのプロジェクトではやらない、になるだろう
Javascript(Node.js)であれば、静的解析にESLint、コードフォーマッターにPrettier、という構成は鉄板だと思う。その場合、importの自動整形ってどうなの?について考えてみたい。
Integrating with Lintersに書かれている通り、Prettierとしては基本的にはESLintとPrettierは分けて使われるべき(コードのスタリングに関してはPrettierが担うべきでESLintがスタイル以外の静的解析に専念すべし)という考え方をしている。
・You end up with a lot of red squiggly lines in your editor, which gets annoying. Prettier is supposed to make you forget about formatting – and not be in your face about it!(エディタに赤いジグザグ線がたくさん表示され、イライラしてしまいます。Prettierは書式設定のことを忘れさせてくれるものであり、また、書式設定に煩わされないものです)
・They are slower than running Prettier directly.(直接Prettierを動かすより遅い)
・They’re yet one layer of indirection where things may break.(このように、物事が壊れる可能性のある間接的なレイヤーがまだ1つあるのです)
つまり、ESLintの設定の実装的な話で言えば、ESLintが持つスタイルに関するルールはeslint-config-prettierを使いoffにし、スタイルに関してPrettierと衝突するような状態を避けるように設定した上で、Prettierのコマンド(prettier --write
)でフォーマッティングする、という考え方をしている。
という事は…、今回取り上げているimportの自動整形についてはコードのスタイルに関する話なのでESLintでやるのはPrettierの思想的にはNGになるので、結論としてimportの自動整形は「なし」に落ち着く気がする(ESLintとprettierも参照)。
※ちなみに、ESLintの方でもsort-import does not auto fix #11542で議論されているように、importの自動整形はしないと決めているようである。詳細はsort-importsのルールではeslint --fixが効かない!?を参照)
※ESLintのルールにPrettierのコードスタイルのルールを組み込み、コードのスタイルも静的解析でエラーにさせる方法も実はあり、それについてはprettier についてを参照。ただし、PrettierのルールをESLintに組み込まずとも、Git hooks(simple-git-hooks)などを使う事でgit commitなどのタイミングで自動整形を走らせる事はできるので、ESLintにPrettierのルールを組み込む必然性はない(Git hooksでコードフォーマッターが動くのであれば、エディターの差やコマンドの実行し忘れなども防げるので)。
Prettierが推奨する設定の例として
上記で見てきたように、スタイルに関する部分はPrettierに全て任せるようにするには以下のように.eslintrc.json
を設定すればいい。
$ yarn add --dev eslint-config-prettier
{
...
"extends": [
...
"prettier" // <- extendsの末尾に記載するのがポイント
],
...
}
このようにする事で、Prettierのスタイルルールと衝突するルールをOffにし、ESLintのチェックでコードのスタイルに関するエラーが出なくなる。
ちなみに、コードのスタイルに関するエラーが出ている状態の例としては以下の画像のようなイメージで、これがPrettierが
You end up with a lot of red squiggly lines in your editor, which gets annoying. Prettier is supposed to make you forget about formatting – and not be in your face about it!(エディタに赤いジグザグ線がたくさん表示され、イライラしてしまいます。Prettierは書式設定のことを忘れさせてくれるものであり、また、書式設定に煩わされないものです)
と言っている事(詳細はprettier についてを参照)。
ソースコード全体は以下。
※Prettierの推奨設定を行う方法については、ESLint・Prettierを併用してコードスタイルのチェックはPrettierにまかせてみたなどの記事も参考になる。
まとめとして
上記で見てきたように、importの自動整形はやらないという感じになりそうだな~と思う。
とは言えやりたいという場合には、以下のおまけにあるような方法でimportの自動整形をする事は可能。
おまけ
ESLintのルールsort-imports
でimportの順番をエラー表示する
.eslintrc.json
に以下のようにsort-imports
を記載するだけ。
{
...
"rules": {
...
"sort-imports": "warn"
},
...
}
ソースコード全体は以下。
実際にESLintをかけてみると…
[root@localhost node-express]# npx eslint .
/root/workspace/node-express/src/middleware/custome-openapi-validator.js
3:1 error Imports should be sorted alphabetically sort-imports
4:1 error Expected 'all' syntax before 'single' syntax sort-imports
✖ 2 problems (2 errors, 0 warnings)
のようにエラーが表示される(VS CodeでESLintのExtensionが入っていれば以下の画像のようにエラーが図示される)。
※ESLintのルール設定方法はConfiguring Rulesに書かれている通りで、上記ではerrorになるように設定いるが、warnにしたりもできる。warnに設定すると以下のようになる。
[root@localhost node-express]# npx eslint .
/root/workspace/node-express/src/middleware/custome-openapi-validator.js
3:1 warning Imports should be sorted alphabetically sort-imports
4:1 warning Expected 'all' syntax before 'single' syntax sort-imports
✖ 2 problems (0 errors, 2 warnings)
※ちなみに、sort-imports
のルールは、よくESLintの設定で行うであろう"extends": [ eslint:recommended ]
には含まれていないので、自分で手動で追加するか、全てのルールを継承するeslint:all
を設定する必要がある。ESLintのextendsについてはextendsを参照。
sort-imports
のルールではeslint --fix
が効かない!?
The --fix option on the command line can automatically fix some of the problems reported by this rule.(コマンドラインの-fixオプションは、このルールで報告された問題のいくつかを自動的に修正することができます)
と書かれているし、RulesのSuggestionsの項に、以下の図の通りfixable
となっているので自動で修正されそうな気がする。
が、sort-import does not auto fix #11542で議論されているように、
However, I don't think it would be safe for sort-imports to autofix code because it could change the evaluation order of the imported modules, which could unexpectedly affect how the code works.(sort-importによるコードの自動修正は、インポートされたモジュールの評価順序を変更し、コードの動作に予期せぬ影響を与える可能性があるため、安全とは言えないと考えています)
との事なので、自動で修正はされないという事になっている。実際に手元でやってみたが、自動で修正はされなかった。
[root@localhost node-express]# npx eslint --fix .
/root/workspace/node-express/src/middleware/custome-openapi-validator.js
3:1 error Imports should be sorted alphabetically sort-imports
4:1 error Expected 'all' syntax before 'single' syntax sort-imports
✖ 2 problems (2 errors, 0 warnings)
そのため、もし自動でimportの順序を直したい場合には以下の章で取り上げるeslint-plugin-importを利用する事になる。
eslint-plugin-importを使ってimportを自動整形する
使い方は公式にある通りで、パッケージを追加し、recommendと言われているルールはひとまず継承するように設定する。
yarn add --dev eslint-plugin-import
{
...
"extends": [
"eslint:recommended",
"plugin:import/recommended",
...
],
...
}
ソースコード全体は以下。
ここで1点、ググると以下のようにextendsに設定してさらにplugins
にまでimports
を記載しているものを見かけるが、extendsしているならpluginsの設定は不要。理由はソースコードを見ればわかるように、plugin:import/recommended
をextendsに記載するとplugins: ['import'],
やrules: {...}
、parserOptions: {...}
が自身の.eslintrc.jsonにも継承されるため。
肝心の自動整形のためのルールはorderというものになるので、以下のように設定すると、eslint --fix
でimportを自動整形してくれるようになる。
{
...
"extends": [
"eslint:recommended",
"plugin:import/recommended",
...
],
"rules": {
...
"import/order": [
"error",
{
"alphabetize": { "order": "asc" }
}
]
},
...
}
※注意として、"sort-imports": "error"
が残っていると以下のようにルールが競合してしまいエラーが残り続けるので、eslint-plugin-importを利用する場合にはsort-importsはoffにする必要があるだろう。
[root@localhost node-express]# npx eslint --fix .
/root/workspace/node-express/src/index.js
6:1 error Imports should be sorted alphabetically sort-imports
/root/workspace/node-express/src/middleware/custome-openapi-validator.js
3:1 error Expected 'all' syntax before 'single' syntax sort-imports
✖ 2 problems (2 errors, 0 warnings)
※今回、.eslintrc.json
にimport/order
のルールを明示的に設定していたが、これはデフォルトのルールセット(configにあるもの)にはなさそうなため、自分で明示的的に設定する必要があったため(extendsしても有効にならないという意味)。