React のプロジェクトで import の並び順を揃えて見通しを良くしたい
前提
create-react-app --template typescript
で作成したプロジェクトに ESLint と Prettier を導入してある
"react-scripts": "^5.0.0"
"react": "^17.0.2"
"typescript": "~4.1.5"
"eslint": "^8.6.0"
"prettier": "2.5.1"
1. 使用してない import 自動削除する
eslint-plugin-unused-imports を使用する
$ npm i -D eslint-plugin-unused-imports
.eslintrc.json
に設定を追加する
{ "plugins": [ "react", "@typescript-eslint", + "unused-imports" ], "rules": { + "@typescript-eslint/no-unused-vars": "off", // or "no-unused-vars" + "unused-imports/no-unused-imports": "error", + "unused-imports/no-unused-vars": [ + "warn", + { "vars": "all", "varsIgnorePattern": "^_", "args": "after-used", "argsIgnorePattern": "^_" } + ], } }
"@typescript-eslint/no-unused-vars"
… unused-imports のルールとバッティングするので off にする"unused-imports/no-unused-imports"
… unused-imports の使用していない import に対するルール"unused-imports/no-unused-vars"
… unused-imports の no-unused-vars ルール"vars": "all"
… global スコープを含め全ての変数をチェックする"varsIgnorePattern": "^_",
… チェックしない変数を Regexp で指定できる。_
で始まる変数が使用されてなくても OK にする"args": "after-used"
… 引数の使用してない変数に対するチェック。使用している変数が引数の最後の変数であれば、それより前の引数は使ってなくても OK- "argsIgnorePattern": "^_" …
varsIgnorePattern
の引数版。チェックしない引数を Regexp で指定できる。_
から始まる引数は使用のチェックを行わない
cf. no-unused-vars - Rules - ESLint - Pluggable JavaScript linter
2. import の並び順を揃える
eslint-plugin-import で import の順番を強制できる
$ npm i -D eslint-plugin-import
.eslintrc.json
に設定を追加
{ "plugins": [ "react", "@typescript-eslint", "unused-imports", + "import" ], "rules": { // … 略 + "import/order": [] } }
import の並び順のルール
.eslintrc.json
の import/order
ルール内に import の並び順のルールを記述する
GitHub にあるルールのドキュメント が参考になる
e.g.
{ "rules": { "import/order": [ "error", { // グループごとの並び順 "groups": [ "builtin", // 1. fsや path などの node "builtin" のモジュール "external", // 2. npm install したパッケージ "internal", // 3. webpack などでパス設定したモジュール ["parent", "sibling"], // 4. 親階層と小階層のファイル "object", // object"-imports "type", // 型だけをインポートする type imports "index" // 同階層のファイル ], // グループごとに改行を入れる "newlines-between": "always", // "never" を指定すると改行なし // FIXME: ちょっとよく分かってない // This defines import types that are not handled by configured pathGroups. This is mostly needed when you want to handle path groups that look like external imports. "pathGroupsExcludedImportTypes": ["builtin"], // アルファベット順・大文字小文字を区別しない "alphabetize": { "order": "asc", "caseInsensitive": true }, // パターンマッチしたものをグループにする // "newlines-between": "always" の場合は pathGroups ごとに空行が入る "pathGroups": [ // react 関連を external より前にする // "pathGroupsExcludedImportTypes": ["react"], にしてみたが `react`, `react-dom` などが別グループになってしまったので pattern で無理やり同じグループにした { "pattern": "react**", "group": "external", "position": "before" }, // `@/app`, `@/features/`, `@/libs` の import をひとグループにして internal の前に { "pattern": "{@/app/**,@/features/**,@/libs/**}", "group": "internal", "position": "before" }, // `@/components`, `@/pages` の import をグルーピング { "pattern": "{@/components/**,@/pages/**}", "group": "internal", "position": "before" }, // CSS module を一番最後に { "pattern": "./**.module.css", "group": "index", "position": "after" } ] } ] } }
ESLint でフォーマットするスクリプトを追加
未使用の import の削除も import の順番の強制も ESLint のルールなので eslint --fix
で修正できる
コードフォーマットの prettier 合わせてフォーマットできるように npm-script を作成しておくと便利
package-json
{ "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", + "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'", + "lint:fix": "eslint --fix 'src/**/*.{js,jsx,ts,tsx}'", + "format": "npm run lint:fix && prettier --write 'src/**/*.{js,jsx,ts,tsx}'", "eject": "react-scripts eject" }
👇 フォーマット
$ npm run format
ESLint が実行された後に prettier でフォーマットされていれば OK
VS Code の保存時にフォーマットする
コマンド叩き忘れがないように保存時に自動フォーマットするようにしておく
.vscode/settings.json
{ "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true, "editor.codeActionsOnSave": { "source.fixAll.eslint": true }, }
おわり
ESLint 関連のルール ドキュメントの説明を見てもよくわからんのが結構あるので英語力…ってなる。
個人的にはどうなるのかのサンプルコードを載せていたほうが親切だよなって感じたので、自分がなにか公開する際はそうしようって思いました。
ESLint + Prettier の設定毎回毎回何度も作ってる気がするので、そろそろテンプレート化しておきたい。(作る度にパッケージのアップデートで指定方法が変わってたりするから毎回手直しすることにになってるけど…)
[参考]
- GitHub - sweepline/eslint-plugin-unused-imports: Package to separate no-unused-vars and no-unused-imports for eslint as well as providing an autofixer for the latter.
- GitHub - import-js/eslint-plugin-import: ESLint plugin with rules that help validate proper imports.
- React+TSプロジェクトで便利だったLint/Format設定紹介
- importの順番をルール化して自動で整列させるeslint-plugin-import