Migrate To Eslint9

早在去年9月,ESLint官方博客就预告了9.0版本,弃用和删除了大量的API和规则,其中格式化规则的删除和旧配置文件eslintrc的弃用更改幅度最大。几个月测试下来,4月5日尘埃落定,9.0版本正式发布。 由于更改东西很多,所以官方给了一份详细的迁移指南 eslint.org/docs/latest…

注意:ESlint9.0支持的Node.js版本是LTSv18.18.0+和v20,不支持v19以及之前的所有版本。

Project Migration

首先安装 @aoviz/lint 的最新版本

.eslintrc.js.eslintignore 文件现在都被合并至一个文件 eslint.config.mjs,下面给出迁移后的项目配置,可以根据具体需求自行更改

import aoviz from '@aoviz/eslint-plugin';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import js from '@eslint/js';
import { FlatCompat } from '@eslint/eslintrc';
import { COLOR_MAP } from './libs/styles/variables.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
  baseDirectory: __dirname,
  recommendedConfig: js.configs.recommended,
  allConfig: js.configs.all
});

export default [
  ...compat.extends('./node_modules/@aoviz/lint/eslint/index.js'),
  {
    languageOptions: {
      parserOptions: {
        tsconfigRootDir: __dirname
      }
    },
    plugins: {
      '@aoviz': aoviz
    },
    rules: {
      '@aoviz/build-in-color': ['error', COLOR_MAP],
      '@typescript-eslint/no-unused-vars': 'off',
      'no-restricted-imports': [
        'warn',
        {
          paths: [
            {
              name: 'dayjs',
              message: '请使用 @libs/time/utils 的 dayjs 代替'
            },
            {
              name: '@bixi-design/core',
              importNames: ['SafeContainer'],
              message: '请使用  @libs/monitor/components 的 SafeContainer 代替'
            },
            {
              name: 'react-router-dom',
              importNames: ['useNavigate', 'useSearchParams'],
              message: '不允许直接操作路由,请使用 @libs/router/hooks 中的 hooks 代替'
            }
          ]
        }
      ]
    }
  }
];

@typescript-eslint/no-unused-vars 这条规则目前有会误检测 TS 类型的 Bug,建议暂时不启用

由于 Eslint 前后版本不兼容,所以 package.json 文件也要做一些改造

  "scripts": {
    "eslint": "eslint . --cache",
    "eslint:staged": "lint-staged",
  },
  "resolutions": {
    "@typescript-eslint/eslint-plugin": "7.18.0",
    "eslint-plugin-react": "7.35.0",
    "eslint-plugin-react-hooks": "^5.1.0-rc-3208e73e-20240730",
  },
  "lint-staged": {
    "apps/**/*.{js,jsx,tsx,ts}": "npx eslint apps/ --cache",
    "libs/**/*.{js,jsx,tsx,ts}": "npx eslint libs/ --cache",
    "portal/**/*.{js,jsx,tsx,ts}": "npx eslint portal/ --cache"
  }

为避免不同版本的插件冲突,需要手动指定一下这三个插件的版本

对应的,husky 改为

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn eslint:staged

dockerfile 更新 node 版本与脚本

FROM dockerhub.datagrand.com/frontend_utils/node:20.12.2 as builder

# build
RUN yarn eslint
RUN yarn build
RUN rm -rf dist/*.js.map && rm -rf dist/*.css.map