前言
距离 9.0 版本发布已经两个多月了,主流框架或者工具基本都已经适配,一起来体验新版本吧~
Breaking Changes
简单列举大家可能会遇到的 change,详情查看官方 release note
不再支持 Node v19.x 和 LTS18.18.0 版本
名词解释:
- LTS:Long-Term Support 是 Node 的长期支持版本(维护和安全更新),通常每隔两年发布一次,特点是稳定和可靠性,建议生产使用。
- 非 LTS(current):是 Node 的最新开发版本,通常每隔几个月发布一次,包含最新的功能和实验特性,缺乏稳定性。
Flat 配置文件取代 eslintrc 配置
新版
eslint.config.{js,cjs,mjs}已经取代了.eslintrc配置文件,如果你是“怀旧派”可以将你的环境变量ESLINT_USE_FLAT_CONFIG设为false,但 Implement Flat Config 中已经明确表示在下一阶段(10.x)中会移除对旧配置文件的兼容。
eslint.config.js
eslint 9中支持Common JS和ESM两种配置文件格式,推荐使用ESM。
const eslint = require('@eslint/eslint');
module.exports = [
eslint.configs.recommended,
// your config
{
name: 'custom-lint-config',
files: ['*.js'],
rules: {
'no-undef': 0,
},
},
];
import eslint from '@eslint/eslint';
export default [
eslint.configs.recommended,
// your config
{
name: 'custom-lint-config',
files: ['*.js'],
rules: {
'no-undef': 0,
},
},
];
新 Rule:no-useless-assignment
no-useless-assignment规则用于检测无用的赋值操作,例如let id = 1234;中1234没有被使用。
let id = 1234; // 1234 is never used
id = calculateId();
可无参数运行 eslint 命令
在
flat config中,不向CLI中传入任何参数时,eslint会默认对当前目录进行lint检查,如:npx eslint
npx eslint
基本使用
使用
eslint推荐配置来初始化lint规则。在flat config中,配置顺序也尤为重要,若规则相同,后面的配置会覆盖前面的配置。 或者定义全局生效的rules和ignores, 来覆盖。
yarn add eslint @eslint/js -D
若你的配置对象的
key仅有files或ignores时,那么这些规则将全局生效。
import eslint from '@eslint/js';
const flatConfig = [
{
name: 'some global cofig here',
languageOptions: {
globals: {
// ...
},
},
rules: {
'no-unused-vars': 0,
},
},
{
name: 'some user comfig here',
files: ['src/**.{ts, tsx}'],
rules: {
// ...
},
},
// global files
{
files: ['src/**.{ts, tsx}'],
},
// global ignores
{
ignores: ['dist'],
},
];
export default [
eslint.configs.recommended,
// ... your config
...flatConfig,
];
相关配置迁移
本文档包含
typescript、react、prettier、babel等常用配置的升级迁移,更多配置请查看官方文档的迁移指南或查看仓库说明。
typescript-eslint
typescript-eslint提供了在flat config中使用推荐配置来帮你快速开箱,该推荐配置默认包含@typescript-eslint/parser和@typescript-eslint/eslint-plugin。
使用 typescript-eslint 推荐配置
若需要覆盖
rules,需定义global rules
yarn add typescript typescript-eslint -D
import eslint from '@eslint/js';
import tsEslint from 'typescript-eslint';
const flatConfig = [
{
name: 'some comfig here',
rules: {
// ...
},
},
// global rules
{
rules: {
'@typescript-eslint/ban-types': 2,
},
},
];
export default tsEslint.config(
eslint.configs.recommended,
...flatConfig,
...tsEslint.configs.recommended,
);
使用 @typescript-eslint/parser 自定义
yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser -D
import eslint from '@eslint/js';
import tsEslintPlugin from '@typescript-eslint/eslint-plugin';
import tsEslintParser from '@typescript-eslint/parser';
const flatConfig = [
// ....
];
const customTsFlatConfig = [
{
// any string
name: 'typescript-eslint/base',
languageOptions: {
parser: tsEslintParser,
sourceType: 'module',
},
files: ['**/*.{ts,tsx}'],
// custom rules or use recommended rules
rules: {
...tsEslintPlugin.configs.recommended.rules,
'@typescript-eslint/ban-types': 2,
'@typescript-eslint/no-confusing-non-null-assertion': 2,
},
plugins: {
// ts 语法特有的规则,例如泛型
'@typescript-eslint': tsEslintPlugin,
},
},
];
export default [eslint.configs.recommended, ...flatConfig, ...customTsFlatConfig];
@babel/eslint-parser
@babel/eslint-parser是babel官方提供的parser,支持babel的所有语法特性,包括jsx、flow、typescript等。大部分情况下,你可能只需要@typescript-eslint/parser即可
yarn add @babel/eslint-parser @babel/preset-env -D
配置时请注意多个
parser之间顺序。
import eslint from '@eslint/js';
import tsEslintPlugin from '@typescript-eslint/eslint-plugin';
import tsEslintParser from '@typescript-eslint/parser';
import babelParser from '@babel/eslint-parser';
const flatConfig = [
// ....
];
const customTsFlatConfig = [
// ...
];
const bableConfig = {
name: 'babel-parser',
languageOptions: {
parser: babelParser,
parserOptions: {
babelOptions: {
babelrc: false,
configFile: false,
browserslistConfigFile: false,
presets: ['@babel/preset-env'],
},
requireConfigFile: false,
},
},
};
export default [eslint.configs.recommended, ...flatConfig, bableConfig, ...customTsFlatConfig];
eslint-plugin-react、eslint-plugin-react-hooks
同样,
eslint-plugin-react也提供了flat config的推荐配置,你可以直接使用它们。
yarn add eslint-plugin-react eslint-plugin-react-hooks globals -D
import eslint from '@eslint/js';
import tsEslintPlugin from '@typescript-eslint/eslint-plugin';
import tsEslintParser from '@typescript-eslint/parser';
import babelParser from '@babel/eslint-parser';
import reactPlugin from 'eslint-plugin-react';
import reactHooksPlugin from 'eslint-plugin-react-hooks';
import globals from 'globals';
const flatConfig = [
// ....
];
const customTsFlatConfig = [
// ...
];
const bableConfig = {
// ...
};
const reactConfig = {
name: 'react-eslint',
files: ['**/*.{js,jsx,mjs,cjs,ts,tsx}'],
plugins: {
react: reactPlugin,
'react-hooks': reactHooksPlugin,
},
languageOptions: {
...reactPlugin.configs.recommended.languageOptions,
// parserOptions: {
// ecmaFeatures: {
// jsx: true,
// },
// },
globals: {
...globals.es2022,
...globals.browser,
...globals.node,
},
},
rules: {
...reactPlugin.configs.recommended.rules,
'react/react-in-jsx-scope': 0,
},
settings: {
react: {
// 需要显示安装 react
version: 'detect',
},
},
};
export default [
eslint.configs.recommended,
...flatConfig,
bableConfig,
reactConfig,
...customTsFlatConfig,
];
或者直接使用 推荐配置
import reactPlugin from 'eslint-plugin-react';
export default [reactPlugin.configs.recommended];
eslint-plugin-prettier
eslint-plugin-prettier用于将prettier的格式化规则转换为eslint的规则,以便在eslint中使用prettier的格式化规则。
yarn add eslint-plugin-prettier eslint-config-prettier -D
import eslint from '@eslint/js';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
export default [eslint.configs.recommended, eslintPluginPrettierRecommended];
ESLint Config Inspector
使用
@eslint/config-inspector来检测配置的规则或parser是否命中。match的config name为每项flat config的name


总结
配置汇总
import eslint from '@eslint/js';
import tsEslintPlugin from '@typescript-eslint/eslint-plugin';
import tsEslintParser from '@typescript-eslint/parser';
import tsEslint from 'typescript-eslint';
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
import reactPlugin from 'eslint-plugin-react';
import reactHooksPlugin from 'eslint-plugin-react-hooks';
import babelParser from '@babel/eslint-parser';
import globals from 'globals';
const customTsFlatConfig = [
{
name: 'typescript-eslint/base',
languageOptions: {
parser: tsEslintParser,
sourceType: 'module',
},
files: ['**/*.{ts,tsx}'],
rules: {
...tsEslintPlugin.configs.recommended.rules,
'@typescript-eslint/ban-types': 2,
'@typescript-eslint/no-confusing-non-null-assertion': 2,
},
plugins: {
// ts 语法特有的规则,例如泛型
'@typescript-eslint': tsEslintPlugin,
},
},
];
const flatConfig = [
// 全局生效的规则
{
name: 'global config',
languageOptions: {
globals: {
...globals.es2022,
...globals.browser,
...globals.node,
},
parserOptions: {
warnOnUnsupportedTypeScriptVersion: false,
},
},
rules: {
'no-dupe-class-members': 0,
'no-redeclare': 0,
'no-undef': 0,
'no-unused-vars': 0,
},
},
{
name: 'react-eslint',
files: ['**/*.{js,jsx,mjs,cjs,ts,tsx}'],
plugins: {
react: reactPlugin,
'react-hooks': reactHooksPlugin,
},
languageOptions: {
...reactPlugin.configs.recommended.languageOptions,
// parserOptions: {
// ecmaFeatures: {
// jsx: true,
// },
// },
},
rules: {
...reactPlugin.configs.recommended.rules,
'react/react-in-jsx-scope': 0,
},
settings: {
react: {
// 需要显示安装 react
version: 'detect',
},
},
},
{
name: 'babel-parser',
languageOptions: {
parser: babelParser,
parserOptions: {
babelOptions: {
babelrc: false,
configFile: false,
browserslistConfigFile: false,
presets: ['@babel/preset-env'],
},
requireConfigFile: false,
},
},
},
{
ignores: ['dist'],
}
];
// export default tsEslint.config(
// eslint.configs.recommended,
// eslintPluginPrettierRecommended,
// ...flatConfig,
// ...tsEslint.configs.recommended,
// );
export default [
eslint.configs.recommended,
eslintPluginPrettierRecommended,
...flatConfig,
...customTsFlatConfig,
];