背景:老项目没有配 eslint,或者 eslint 规则松散,配了跟没配一样。需要加上 eslint 或者加入更加严格的规则。
做减法
选择一个规则比较严格的扩展包,根据实际情况把不需要的规则一个个关掉,这个过程中一些歪瓜裂枣的写法无法遁形。个人喜欢用 eslint-config-airbnb ,常规配置如下:
module.exports = {
root: true,
globals: {
page: true,
REACT_APP_ENV: true,
UMI_ENV: true,
},
settings: {
react: {
version: 'detect',
},
},
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: true,
},
},
extends: [
'airbnb',
'plugin:@typescript-eslint/recommended',
'prettier',
'plugin:react/recommended',
],
plugins: ['prettier', 'react', 'react-hooks', '@typescript-eslint'],
rules: {
'prettier/prettier': 'error',
'@typescript-eslint/no-explicit-any': 'error',
eqeqeq: 'error',
'@typescript-eslint/no-unused-vars': [
'error',
{
vars: 'local',
args: 'none',
varsIgnorePattern: 'usePresenter|^I',
caughtErrors: 'none',
},
],
},
};
根据配置,全量代码 lint 一遍:
"lint": "eslint --ext .ts,.tsx,.js,.jsx --fix src/",
执行
yarn lint
你可能会得到这样的大礼包
根据实际情况把不需要的规则减去,我的配置如下:
module.exports = {
root: true,
globals: {
page: true,
REACT_APP_ENV: true,
UMI_ENV: true,
},
settings: {
react: {
version: 'detect',
},
},
parserOptions: {
parser: '@typescript-eslint/parser',
ecmaFeatures: {
jsx: true,
},
},
extends: [
'airbnb',
'plugin:@typescript-eslint/recommended',
'prettier',
'plugin:react/recommended',
],
plugins: ['prettier', 'react', 'react-hooks', '@typescript-eslint'],
rules: {
'prettier/prettier': 'error',
'@typescript-eslint/no-explicit-any': 'error',
eqeqeq: 'error',
'@typescript-eslint/no-unused-vars': [
'error',
{
vars: 'local',
args: 'none',
varsIgnorePattern: 'usePresenter|^I',
caughtErrors: 'none',
},
],
'react-hooks/exhaustive-deps': 0,
'@typescript-eslint/no-empty-function': 0,
'@typescript-eslint/no-var-requires': 0,
'react/react-in-jsx-scope': 0,
'react/display-name': 0,
'@typescript-eslint/no-non-null-assertion': 0,
'react/jsx-filename-extension': 0,
'react/function-component-definition': 0,
'import/no-unresolved': 0,
'import/extensions': 0,
'arrow-body-style': 0,
'react/jsx-no-useless-fragment': 0,
'react/jsx-props-no-spreading': 0,
'react/no-unstable-nested-components': 0,
'jsx-a11y/alt-text': 0,
'prefer-template': 0,
'import/prefer-default-export': 0,
'no-use-before-define': 0,
'object-shorthand': 0,
camelcase: 0,
radix: 0,
'class-methods-use-this': 0,
'import/no-extraneous-dependencies': 0,
'prefer-destructuring': 0,
'jsx-a11y/click-events-have-key-events': 0,
'jsx-a11y/no-static-element-interactions': 0,
'consistent-return': 0,
'no-unsafe-optional-chaining': 0,
'jsx-a11y/media-has-caption': 0,
'react/destructuring-assignment': 0,
'no-plusplus': 0,
'no-else-return': 0,
'no-console': 0,
'prefer-exponentiation-operator': 0,
'func-names': 0,
'react/require-default-props': 0,
'no-return-assign': 0,
'no-lonely-if': 0,
'no-empty': 0,
'jsx-a11y/anchor-is-valid': 0,
'no-restricted-properties': 0,
'operator-assignment': 0,
'prefer-promise-reject-errors': 0,
'no-prototype-builtins': 0,
'prefer-object-spread': 0,
'no-param-reassign': 0,
'@typescript-eslint/no-empty-interface': 0,
},
};
处理老代码
按上面配置执行 lint 时,新加的代码是能通过的。但是原来的代码可能还是一大堆问题
原来的代码如果不再改动,那么我们完全不需要去管了,但这是不可能的。一旦有迭代需要改原来的代码,哪怕只改了一行代码,提交代码的时候 git 钩子是过不去的,而且打开这些代码时,编辑器估计是一片红。
秉着别人拉的shi,凭什么要我去扒的原则,我们不想去改迭代需求之外的代码,但是又要能正常提交。需要借助 eslint 的一个配置,那就是 overrides。
overrides 允许给特定的文件配置特定的rules,比如:
overrides: [
{
files: [
'src/pages/activities/list.tsx',
],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
eqeqeq: 'off',
},
},
],
需要将所有的旧代码文件配置到 files 数组里,这可是个体力活,写个脚本去处理:
import glob from 'glob';
import path from 'path';
import fs from 'fs-extra';
export const getFiles = () =>
new Promise<string[]>((resolve, reject) => {
glob(
'**',
{
cwd: path.join('H:/你的项目地址/src'),
ignore: [],
nodir: true,
dot: true,
},
(err, files) => {
if (err) {
reject(err);
return;
}
resolve(files);
},
);
});
getFiles().then((files) => {
fs.writeFileSync(
'./overrides.txt',
files
.filter(
(s) =>
s.includes('.vue') ||
s.includes('.ts') ||
s.includes('.js') ||
s.includes('.tsx'),
)
.map((s) => `'src/${s}',`)
.join('\r'),
);
});
把文件 overrides.txt 里的内容复制到 files 数组中。内容可能会非常的多,可以将 overrides 配置在独单的文件里,比如:
./ignoreCheckAndLintFiles/.eslintrc.js 配置到这个文件里
// files只允许删减,不允许增加
module.exports = {
overrides: [
{
files: [
'src/pages/activities/list.tsx',
// ...省略
],
rules: {
'@typescript-eslint/no-explicit-any': 'off',
eqeqeq: 'off',
// ... 省略
},
},
],
};
在项目根目录的 .eslintrc.js 文件中引入
const overrides = require('./ignoreCheckAndLintFiles/.eslintrc.js');
module.exports = {
// ... 省略
overrides: overrides.overrides,
};
// 可以添加规则 删除、忽略规则先说明原因 请严格执行
再执行lint ,强迫症都治好了
ts check 配置
配置 tsconfig.json 文件,禁止使用 any,严格模式
"noImplicitAny": true,
"strict": true
配置 ts ckeck 命令
"tsc": "tsc --noEmit --skipLibCheck"
老代码肯定是过不去的,配置 exclude 数组,把旧代码文件放进去,也是配置在单独的文件里。
./ignoreCheckAndLintFiles/tsconfig.json
{
"extends": "../tsconfig.json",
"exclude": [
"../src/pages/login.tsx"
// ... 省略
]
}
也是用脚本去处理
import glob from 'glob';
import path from 'path';
import fs from 'fs-extra';
export const getFiles = () =>
new Promise<string[]>((resolve, reject) => {
glob(
'**',
{
cwd: path.join('H:/VankeService/katarina/src'),
ignore: [],
nodir: true,
dot: true,
},
(err, files) => {
if (err) {
reject(err);
return;
}
resolve(files);
},
);
});
getFiles().then((files) => {
fs.writeJSONSync('./exclude.json', {
extends: '../tsconfig.json',
exclude: files
.filter(
(s) => s.includes('.vue') || s.includes('.ts') || s.includes('.tsx'),
)
.map((s) => `../src/${s}`),
});
});
把 exclude.json 内容复制到 ./ignoreCheckAndLintFiles/tsconfig.json
修改 ts check 命令
"tsc": "tsc --project ./ignoreCheckAndLintFiles/tsconfig.json --noEmit --skipLibCheck"
新代码里引入旧代码还是会报错,所以尽量不要再去使用旧代码,或者旧代码里使用
// @ts-ignore