ESLintã®Flat Configã¸ã®ç§»è¡ã¯é²ãã§ã¾ãã§ããããï¼è©¦ãã¦ã¿ãã§ããããï¼
ä»åã¯ãã¯ã³ã´ã®æ°åã¨ã³ã¸ãã¢ãåä»äºã¨ãã¦åãçµãã ãESLintã®Flat Configã¸ã®ç§»è¡ã«é¢ãã¦ããã®æ¹æ³ã¨åµã£ãã¨ããã®ä¹ãè¶ãæ¹ãããä¼ããã¾ãã
ãã®è¨äºã§è¨åãããã¨
- Flat Configã«æ¸ãå¤ããã¨ãã«è¦ãè³æ
- ESLintã®configãFlat Configã«ç§»è¡ããã¨ããconfigs.recommendedãªã©ã®ããªã»ãããç¨ããå ´åã¯FlatCompatã使ã
- eslint-plugin-importã使ç¨ãã¦ãã¨åµã
- ã©ããã£ã¦æ°æ§configãåãã«ãªã£ã¦ãããã¨ã示ãã®ãï¼
ESLintã®Flat Configãæ¸ããã¨ã«ãªãã¾ãã
ããã«ã¡ã¯ãNäºåæ ¡ Web ããã³ãã¨ã³ãéçºãã¼ã ã®sokunoã§ããç§ã¯ç¾å¨4ã¶æã«æ¸¡ãæ°åç ä¿®ãçµã¦ããã®8æããä»ã®ãã¼ã ã«åå ãã¾ããã
ãã¯ã³ã´ã®æ°åç ä¿®ã¯Näºåæ ¡ã®ææã使ã£ãWebéçºã®åºç¤ã«å§ã¾ããããã°ãµã¼ãã¹ãä½ã£ãããåç»æ稿ãµã¤ããä½ã£ããã¨ãé常ã«å®è·µçã§é å±å¾ã®æ¥åã§ããã®çµé¨ã¯é常ã«å½¹ç«ã£ã¦ãã¾ãããã®è©³ç´°ã¯ä»ã®ã¡ã³ãã¼ãç®ä¸å·çä¸ã®ããã§ãã®ã§ãå ¬éããããæ¯éèªãã§ã¿ã¦ãã ããã
ãã¼ã ã«åå ãã¦ããã¯ãéçºã§ä½¿ç¨ããwebpackãstorybookãªã©ã®ãã¼ã«ãå¦ã¶ãããã¡ããã©ããissueãããã¯ã¢ãããã¦ããã ãã¦åå¼·ããªããåãçµãã§ãã¾ãã
ä»åã®ESLintã®Flat Configã¸ã®ç§»è¡ããã®issueã®ã²ã¨ã¤ã§ãã
ææ°æã ã¨æãã¤ããç§ã§ãããããã«ã¤ãã¦ããå 輩ã®ã³ã¡ã³ããæ°ããè¨å®ãã¡ã¤ã«ã®å½¢å¼ã¯ç§ã詳ãããªãã®ã§ããããã¼ã ã®ãªã¼ãã¼ã®berlysiaãããæ¾ã£ããFlat Configã¸ã®ç§»è¡ã¯åµã£ããªããã¨ããã»ãªãããä¸ç©ãªå½±ãè½ã¨ãã¦ãããã¨ã«ãæ®å¿µãªããã¾ã æ°ã¥ããã¨ãã§ãã¾ããã§ããã
ã©ããã¦ç§»è¡ããã®ãï¼
2023å¹´10æ10æ¥ã®è¨äº"Flat config rollout plans"ã«ããã°ãeslintrcã¯è¿ã ãªãªã¼ã¹ãããv9以éã§éæ¨å¥¨ã«ãªãã2024å¹´æ«ããã«ãªãªã¼ã¹ãè¨ç»ããã¦ããv10ã§ã¯åé¤ãããããã§ãã
ãã®ãããç§éã®ãããªCLIã¦ã¼ã¶ã¼ã«é¢ãã¦ããã°v10ã¾ã§ã«ã¯Flat Configã¸ã®æ¸ãæããå®äºãã¦ããå¿ è¦ãããã¾ãã
Flat Configã«ç§»è¡ããã«ã¯
ESLintã®è¨å®ãFlat Configã«æ¸ãç´ãæ¹æ³ã«é¢ãã¦ã¯ã以ä¸ã®å ¬å¼ããã¥ã¡ã³ã(migration guide)ã§æ¦ãç¶²ç¾ ããã¦ãã¾ãã
https://eslint.org/docs/latest/use/configure/migration-guide
ã¾ããããã ãã§ãªãFlat Configã®ããã¥ã¡ã³ãã¨ãããã¾ã§ã®config(以ä¸ãeslintrc)ã«é¢ããããã¥ã¡ã³ããè¦æ¯ã¹ããã¨ãå½¹ç«ã¡ã¾ããã
ä½æ¥æ¹éã決ãã
Flat Configã«æ¸ãæããããã«ãESLintã®ããã¥ã¡ã³ããçºãã¦ããç§ã¯ã
- ã¨ãããããä¸è¨ã®migration guideã«æ²¿ã£ã¦æ¸ãåã
ãã¨ã«æ±ºãã¾ããã
ã¾ããæ°æ§ã®configãåãã«ãªã£ã¦ãããã¨ã確ãããå¿ è¦ãããã¨èãã主ã«ä»¥ä¸ã®2ç¹ã確èªãããã¨ã«ãã¾ããã
- lintãé©ç¨ããããã¡ã¤ã«ãå¤ãã£ã¦ããªãã
- eslintrcã¨Flat Configã§ããã¡ã¤ã«æ¯ã«é©ç¨ããã«ã¼ã«ãåãã«ãªã£ã¦ããã
ã§ãä½ã«ã¤ã¾ãããã®ãï¼
æ¸ãæãã¦ããã«ããã£ã¦ãã©ã®ããããã£ãã©ãã«æ¸ãæãã¦ããã°ãããã¨ãã£ããäºç´°ããªèª¬æã¯migration guideãåç §ãã¦ããã ããã¨ã¨ãã¾ãããã
ç§ãmigration guideã«ãããã£ã¦æ¸ãæãã¦ãããè¦ããä¸ã¯åé¡ãªããããªeslint.config.jsãã§ããããã¾ããã
ãã®ãããeslint.config.jsãèªã¾ãã¦ESLintãå®è¡ãã¾ãããè¡ãã¦ããã¼ï¼ãã¨æããªããEnterãã¼ãæ¼ãã¾ãããå½ç¶ãªãããããªãã¨ã¯ããã¾ãããFlat Configã«å¯¾å¿ãã¦ããªãpluginãããã¤ãã®ã¨ã©ã¼ãåãããã®å¯¾å¿ããããã¨ã«ãªãã¾ããã
次ã®2ç¯ã§çºçããã¨ã©ã¼ã¨å¯¾å¦æ¹æ³ã説æãã¾ãã
ã¤ã¾ãããã¤ã³ãâ : A config object has a "plugins" key defined as an array of strings. ã¿ãããªã®ãåºã
ä¾ãã°eslintrcã§pluginã®recommended
ãªã©ãextends
ã«å
¥ãã¦ããå ´åãFlat Configã§ã¯ä»¥ä¸ã®ããã«æ¸ããããªãã¾ãã
//.eslintrc.js ã®ä¸é¨ (ããã ãã§ã¯åä½ãã¾ãã) module.exports = { extends: [ "eslint:recommended", "plugin:react/recommended", "plugin:import/typescript", ......
// eslint.config.js ã®ä¸é¨ (ããã ãã§ã¯åä½ãã¾ãã) module.exports = [ js.configs.recommended, reactHookPlugin.configs.recommended. reactPlugin.configs.recommended, importPlugin.configs.typescript, ......
ããããç¾æç¹ã§ã¯Flat Configå½¢å¼ããµãã¼ããã¦ããªãpluginãããã表ç¾æ¹æ³ãå¤ãã£ãè¨å®ãå«ããã®ãå ãããã¨ããã¨ãã®keyãæ£ããå½¢å¼ã§ãªãæ¨ã®ã¨ã©ã¼ãåºãããã§ãã
ç§ã®å ´åã¯ä»¥ä¸ã®ã¨ã©ã¼ãé »åºãã¾ããã
A config object has a "plugins" key defined as an array of strings.
ãã®åé¡ã«é¢ãã¦ã¯ãeslintrcå½¢å¼ã®configãFlat Configå½¢å¼ã«å¤æããããã«ãFlatCompatãæä¾ããã¦ãã¾ãã ãããç¨ãã¦ä»¥ä¸ã®ããã«æ¸ãæãããã¨ãã§ãã¾ãã
// eslint.config.js ã®ä¸é¨ (ããã ãã§ã¯åä½ãã¾ãã) const { FlatCompat } = require("@eslint/eslintrc"); const compat = new FlatCompat({}); module.exports = [ // ãã©ã°ã¤ã³ã®å¯¾å¿ã«å¿ãã¦compatãããã js.configs.recommended, //äºææ§ã«åé¡ãªããã°ããã§OK ...compat.extends("plugin:react/recommended"), ...compat.extends("plugin:react-hooks/recommended"), ...compat.extends("plugin:import/typescript"),
ãããããã¨ã§ã»ã¨ãã©ã®pluginã®configs
ãFlat Configã§ã使ç¨ã§ããããã«ãªãã¾ãã
ã¤ã¾ãããã¤ã³ãâ¡: import/namespace ã®ã«ã¼ã«ãã¨ã©ã¼ã«ãªã
次ã«ã¤ã¾ãããã®ã¯ãeslint-plugin-importã®ä¸é¨ã®ã«ã¼ã«ã§ä»¥ä¸ã®ãããªã¨ã©ã¼ãåºããã¨ã§ããã
4:44 error Parse errors in imported module '@testing-library/dom': parserPath or languageOptions.parser is required! (undefined:undefined) import/namespace
â ã¯ããã¥ã¡ã³ãã«ãæ¸ãã¦ãã話ã«ãªãã¾ããããã¡ãã¯pluginã®ã³ã¼ããçºããªããåå ã¨åé¿çãæ¢ããããã«æããã£ã¦ãã¾ãã¾ããã
æçµçã«ã¯ã以ä¸ã®issueãåèã«ãªãã¾ããã
https://github.com/import-js/eslint-plugin-import/issues/2556
è¦ç¹ã¯setting["import/parsers"]
ã§æ¡å¼µåã網ç¾
ãããã¨ã ã¨èãããã¾ãã
ãã®ãããissueä¸ã§ææ¡ããã¦ãã以ä¸ã®ãããªè¨è¿°ã§æ¹åã§ããå¯è½æ§ãããã¾ãã
// https://github.com/import-js/eslint-plugin-import/issues/2556#issuecomment-1555998681 // eslint.config.js ã®ä¸é¨ (ããã ãã§ã¯åä½ãã¾ãã) "import/parsers": { espree: [".js", ".cjs", ".mjs", ".jsx"], "@typescript-eslint/parser": [".ts"], },
ç§éã®å ´åã¯å
¨é¨ @typescript-eslint/parser
ã«é£ããã¾ããã
// eslint.config.js ã®ä¸é¨ (ããã ãã§ã¯åä½ãã¾ãã) 'import/parsers': { "@typescript-eslint/parser": [".js", ".jsx", ".ts", ".tsx"], },
ã«ã¼ã«ãæ°æ§configã§ä¸è´ãã¦ãããã確èªãã
ãã¦ãããããã¨ã©ã¼ã¨ã®æ¦ããä¹ãè¶ãã¦å®äºï¼ã¨ããããã«ã¯è¡ãã¾ãããä½æ¥æ¹éã§ãè¿°ã¹ãããã«ãeslintrcããFlat Configã«ç§»è¡ãããã¨ã«ãã£ã¦æ¬ è½ãã¦ãã¾ã£ãè¨å®ããªããã確ãããå¿ è¦ãããã¾ããå°ãªãã¨ããâ 対象ã¨ãªããã¡ã¤ã«ãå¤ãã£ã¦ããªãããâ¡é©ç¨ãããã«ã¼ã«ãå¤ãã£ã¦ããªããã¯ç¢ºèªãããã¨ããã§ãã
以ä¸ã§ã¯ãã®2ç¹ã«é¢ãã¦ç§ãã©ã®ããã«ç¢ºãããããæ¸ãæ®ãã¾ãã
â 対象ã¨ãªããã¡ã¤ã«ãå¤ãã£ã¦ããªãã
ããã¯ãeslintãå®è¡ããã¨ãã«ã©ã®ãã¡ã¤ã«ãlintãããããç¥ãå¿
è¦ãããã¾ãã--debug
ãªãã·ã§ã³ãæå®ããã¨ãã«åºåãããeslintã®ãããã°åºåãæ´»ç¨ãã¦ãlintãé©ç¨ããããã¡ã¤ã«ä¸è¦§ãä½æãã¾ãã
Flat Configã§ã®ä¸è¦§ã¯ä»¥ä¸ã®ãããªã³ãã³ãã§åå¾ã§ãã
npx -c ' eslint --debug "**/*.{js,ts,tsx}"' |& grep -Po "(?<=Parsing\ssuccessful:)\s\S*"
eslintrcã§ã®ä¸è¦§ã¯ ESLINT_USE_FLAT_CONFIG=false
ãå®ç¾©ãã¦åæ§ã«å®è¡ããã°åå¾ã§ãã¾ãã
npx -c 'ESLINT_USE_FLAT_CONFIG=false eslint --debug "**/*.{js,ts,tsx}"' |& grep -Po "(?<=Parsing\ssuccessful:)\s\S*"
åã«è¡æ°ãåãã§ãããã確èªããã®ã§ãååããã§ãããããããã®configã§åºåããããã¡ã¤ã«ã®é çªã¯å¤ãã£ã¦ãã¾ãã¾ãããã®ãããdiffãè¦ãå ´åã¯è¡ãã½ã¼ãããå¿ è¦ãããã¾ãã
â¡é©ç¨ãããã«ã¼ã«ãå¤ãã£ã¦ããªãã
ããã¯eslintã³ãã³ãã® --print-config
ãªãã·ã§ã³ã使ã£ã¦ç¢ºããããã¾ãããã®ãªãã·ã§ã³ã使ãã¨ãä»»æã®ãã¡ã¤ã«ã«é©ç¨ãããè¨å®ãJSONã§åºåã§ãã¾ãããã®ä¸ã®rules
ãeslintrcã®ã¨ãã¨ãFlat Configã®ã¨ãã§å¤ãã£ã¦ããªããã確èªãã¾ãã
$ npx eslint --print-config hoge.js { "settings": { //ç¥ }, "linterOptions": { //ç¥ }, "languageOptions": { //ç¥ }, "plugins": [ //ç¥ ], "rules": { "constructor-super": [ 2 ], "for-direction": [ 2 ], "getter-return": [ 2 ], //以ä¸ç¥ } }
overrideãããã¦ããªããã®ã¨ãoverrideãã¨ã«è©²å½ãããã¡ã¤ã«ãã²ã¨ã¤ä»¥ä¸é¸ãã§ç¢ºããã¾ãããã¡ãããâ ã§ãã¹ã¦ã®ãã¡ã¤ã«ã®ãã¹ãå¤æãã¦ããã®ã§ãããæ´»ç¨ãã¦å ¨ã¦ã®ãã¡ã¤ã«ããã§ãã¯ãã¦ãè¯ãããããã¾ããã
eslintrcã¨Flat Configã®ããããã§åºåãããrules
ãªãã¸ã§ã¯ããå¾ããããæ¯è¼ãã¦ããã¾ãããªãã¸ã§ã¯ãå士ã®æ¯è¼ã«ã¯deepStrictEqualãç¨ãããã¨ãã§ãã¾ãã
注æç¹ã¨ãã¦ãrules
ãªãã¸ã§ã¯ãã®severity
ã0
, 1
, 2
ã§è¡¨ããã¦ããå ´åã¨off
, warn
, error
ã§è¡¨ããã¦ããå ´åãããã®ã§ãããã¯ã©ã¡ããã«çµ±ä¸ãã¦æ¯è¼ããå¿
è¦ãããã¾ãã
ã¾ã¨ã
ä»åã¯Flat Configã¸ã®ç§»è¡ã«ããã¦ã¤ã¾ãããã¨ããã¨ãæ£ããã§ãããã確èªããããã®æ¹æ³ã¨ããï¼ç¹ã«é¢ãã¦è¿°ã¹ã¾ããã
ç§èªèº«ãESLintã«è©³ãããªãã¾ã¾ç§»è¡ä½æ¥ãããã®ã§ãæããã¦æºç¹åçãã¯ãããã¾ãããã¾ããESLintãpluginã®ã¢ããã«ãã£ã¦ç¶æ³ã¯å¤ããã¾ãã®ã§ææ°ã®ç¶æ³ããèªèº«ã§ãæ¯éã確èªããã ããããé¡ãè´ãã¾ãã
ãããåæ§ã®ã¨ã©ã¼ãè¸ãã§ãã¾ã£ãæ¹ã«ã¯ãã®è§£æ±ºã®ä¸å©ã«ãªãã°å¹¸ãã§ãã
é¢é£ãªã³ã¯
Flat config rollout plans
ESlintã®Flat Configã«é¢ããä»å¾ã®å±æã説æããããã°ã§ã
Configuration Files (New)
Flat Configã®ããã¥ã¡ã³ãã§ã
Configuration Files
eslintrcã®ããã¥ã¡ã³ãã§ã
Configuration Migration Guide
eslintrcããFlat Configã¸ã®ç§»è¡ã¬ã¤ãã§ã
ESLint's new config system, Part 2: Introduction to flat config
Flat Configã®ç´¹ä»ããã°ã§ã
We are hiring!
æ ªå¼ä¼ç¤¾ãã¯ã³ã´ã®æè²äºæ¥ã§ã¯ãä¸ç·ã«æªæ¥ã®å½ããåã®æè²ãã¤ããã¡ã³ãã¼ãåéãã¦ãã¾ãã ã«ã¸ã¥ã¢ã«é¢è«ãè¡ã£ã¦ãã¾ãã ãæ°è»½ã«ãé£çµ¡ãã ããï¼
ã«ã¸ã¥ã¢ã«é¢è«å¿åãã©ã¼ã ã¯ãã¡ã
éçºãã¼ã ã®åãçµã¿ãæè²äºæ¥ã®ä»å¾ã«ã¤ãã¦ã¯ãä»ã®è¨äºãæ¡ç¨è³æãã覧ãã ããã