2024/04/06 ESLint v9がリリースされました🎉
Flat config is now the default and has some changes
とあるように、 v9からは今までとは違うFlat Configという設定方法がデフォルトになります。(ESLINT_USE_FLAT_CONFIG
にfalse
を指定することで今まで通りの設定も使い続けることは可能)
今回は個人で開発しているVue.jsとTypeScriptとPrettierを利用しているサービスでFlat Configに移行してみたので、やったこととかをメモ📝
公式のmigrationガイドもあるので、こちらもご参照ください。
最終結果
元のESLintのconfigファイル .eslintrc.cjs
module.exports = { env: { node: true, browser: true, }, extends: [ "eslint:recommended", "plugin:vue/vue3-recommended", "plugin:vue-scoped-css/base", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended-requiring-type-checking", ], root: true, plugins: ["@typescript-eslint", "prettier"], parser: "vue-eslint-parser", parserOptions: { parser: "@typescript-eslint/parser", ecmaVersion: 2020, sourceType: "module", extraFileExtensions: [".vue"], project: "./tsconfig.json", }, rules: { "prettier/prettier": "error", "no-console": "warn", "@typescript-eslint/no-unused-vars": [ "warn", { argsIgnorePattern: "^_", varsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_", }, ], }, overrides: [ { files: ["*.vue"], rules: { "vue/first-attribute-linebreak": "off", "vue/max-attributes-per-line": "off", "vue/singleline-html-element-content-newline": "off", "vue/html-self-closing": "off", "vue/max-lines-per-block": [ "error", { style: 150, template: 200, script: 150, skipBlankLines: true, }, ], "vue-scoped-css/enforce-style-type": ["error", { allows: ["scoped"] }], "@typescript-eslint/no-redundant-type-constituents": "off", "@typescript-eslint/no-unsafe-assignment": "off", }, }, ], };
Flat Configに移行後 eslint.config.js
import js from "@eslint/js"; import ts from "typescript-eslint"; import vue from "eslint-plugin-vue"; import vueParser from "vue-eslint-parser"; import vueCss from "eslint-plugin-vue-scoped-css"; import prettierConfig from "eslint-plugin-prettier/recommended"; import globals from "globals"; export default [ { ignores: [/* ignores */] }, js.configs.recommended, ...ts.configs.recommendedTypeChecked, ...vue.configs["flat/recommended"], ...vueCss.configs["flat/base"], prettierConfig, { languageOptions: { parser: vueParser, parserOptions: { ecmaVersion: 2020, parser: ts.parser, extraFileExtensions: [".vue"], sourceType: "module", project: ["./tsconfig.json"], }, globals: { ...globals.browser, ...globals.node, }, }, }, { rules: { "prettier/prettier": "error", "no-console": "warn", "@typescript-eslint/no-unused-vars": [ "warn", { argsIgnorePattern: "^_", varsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_", }, ], }, }, { files: ["*.vue", "**/*.vue"], rules: { "vue/first-attribute-linebreak": "off", "vue/max-attributes-per-line": "off", "vue/singleline-html-element-content-newline": "off", "vue/html-self-closing": "off", "vue/max-lines-per-block": [ "error", { style: 150, template: 200, script: 150, skipBlankLines: true, }, ], "vue-scoped-css/enforce-style-type": ["error", { allows: ["scoped"] }], "@typescript-eslint/no-redundant-type-constituents": "off", "@typescript-eslint/no-unsafe-assignment": "off", }, }, ];
やったこと
.eslintignore
からFlat Config内のignores
に移行する
.eslintignore
は以下の通りignores
で指定するように変更になっています。
To ignore files with flat config, you can use the ignores property in a config object. https://eslint.org/docs/latest/use/configure/migration-guide#ignoring-files
以下のようにignores
プロパティに.eslintignore
の内容を文字列の配列に変換して指定するようにしました。
export default [ { ignores: [ /* ignores files */ ] },
各種関連ライブラリの導入方法をFlat Configに対応したものに修正する
元々はextends
等を使って導入していた各種ライブラリをFlat Config対応の導入方法が別途README等に記載されていたので、それに従って利用するように修正しました。
typescript-eslint.
...tseslint.configs.recommended
turns on our recommended config.https://typescript-eslint.io/getting-started#step-2-configuration
eslint-plugin-vue
import pluginVue from 'eslint-plugin-vue' export default [ ...pluginVue.configs['flat/recommended'],
https://eslint.vuejs.org/user-guide/#configuration-eslint-config-js
eslint-plugin-prettier
const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended'); module.exports = [ eslintPluginPrettierRecommended, ];
またFlat Configに対応してないライブラリがある場合には、従来のextends
やplugins
を使って利用することもできるようです。
global、parser周りの設定をlanguageOptions
に移行する
.vue
ファイルに対してTypeScript関連も含めて静的解析させるためにparser
周りの設定以下を参照しlanguageOptions
に移行しました。
- typescript-eslint FAQs | I use a framework (like Vue) that requires custom file extensions, and I get errors like "You should add parserOptions.extraFileExtensions to your config"
- typescript-eslint FAQs | I am running into errors when parsing TypeScript in my .vue files"
基本的にはlanguageOptions
の中にparserOptions
があるので、以前のparser
でvue-eslint-parser
を使いつつparserOptions
のparser
で@typescript-eslint/parser
を使い、extraFileExtensions
も指定することができました。
{ languageOptions: { parser: vueParser, parserOptions: { ecmaVersion: 2020, parser: ts.parser, extraFileExtensions: [".vue"], sourceType: "module", project: ["./tsconfig.json"], }, globals: { ...globals.browser, ...globals.node, }, }, },
また、env
プロパティはlanguageOptions
内のプロパティとしてglobals
を利用して定義するようになっているので対応しました。
In flat config files, the globals, and parserOptions are consolidated under the languageOptions key; the env property doesn’t exist https://eslint.org/docs/latest/use/configure/migration-guide#configuring-language-options
overrides
を削除する
今まではglob
ベースでのルールの切り替えにはoverrides
を利用していましたがFlat Configではデフォルトで機能が提供されているようなので
By default, flat config files support different glob pattern-based configs in exported array. You can include the glob pattern in a config object’s files property. https://eslint.org/docs/latest/use/configure/migration-guide#configuring-language-options
以下のように、overrides
を利用せずにそのまま書くことができます。
export default [ { files: ["*.vue", "**/*.vue"], rules: { /* overrides rules */ }
実行オプションの--ext
は削除されたのでglob
での指定に移行する
元々は以下のような形で拡張子を絞って実行していたのですが、
$ eslint app/javascript spec/javascript --ext .vue,.js,.ts
以下の通りFlat Configではサポートされていないのでglob
ベースの指定に修正しました。
The following CLI flags are no longer supported with the flat config file format:
- --ext
https://eslint.org/docs/latest/use/configure/migration-guide#cli-flag-changes
$ eslint 'app/javascript/**/*.{js,ts,vue}' 'spec/javascript/**/*.{js,ts,vue}'
おわりに
Flat Confg最初はあまり分かっておらず従来の方が読みやすいような?とか思ってたんですが、理解できるとコード量も少なくスッキリ書けそうなのと、自然なJavaScriptに近い形になっており分割とか管理もしやすそう📝✨