为 umijs 框架 添加 hooks 依赖检查规则(exhaustive-deps)

424 阅读2分钟

umijs 提供了开箱即用的lint规则与使用方式; 但是在实际使用中,会发现在jsx/tsx文件中使用hooks, 如果缺少依赖,并没有提示,开发体验不够好。需要开启react-hooks/exhaustive-deps 规则;

首先在.eslintrc.js中添加对应规则(react-hooks umijs已经引入)

 rules: {
    "react-hooks/exhaustive-deps": "warn",
},

发现jsx文件的依赖检查提示出现了:

image.png

这里可以调用nodejs的API来查看文件应用了哪些规则(如果运行时提示依赖缺失,安装即可解决,大部分是umi lint的依赖);

const { ESLint } = require("eslint");
const path = require("path");

const getConfig = async () => {
  const eslint = new ESLint();
  const config = await eslint.calculateConfigForFile(
    path.join(__dirname, "./src/pages/Chart/hooks/useNodeData.ts")
  );

  console.log(config);
};

getConfig();

eslint 配置文件的一些规则:

为不同的文件配置不同的规则:例如js与ts文件应用不同的parser,因为babel/eslint-parser 官方已经说明不再支持ts的检查,避免重复校验,并推荐@typescript-eslint, 其实eslint-parser 也可以转换 tsx, ts为eslint 支持的estree, 但是为了一些ts 校验,需要为ts,tsx文件引入额外的一些规则,需要单独为它们指定为typescript-eslint/parser 来解析;

typescript-eslint 提供了parser和eslint-plugin;

parser 主要是调用TypeScript Compiler, 将ts 的sourcecode转换为TypeScript AST , 然后将TS AST 转为ESTree;

eslint-plugin 主要是提供相应的rule,供eslint对转换的estree的某些不识别的节点进行处理识别;

通过overrides来为不同的文件指定不同的parse和rules;下面为umijs的eslint的部分代码:

 parser: require.resolve("@babel/eslint-parser"),
 plugins: ["react", "react-hooks"],
 settings: {
    react: {
      version: "detect"
    }
 },
 env: {
    browser: true,
    node: true,
    es2022: true,
    jest: true
 },
 rules: import_recommended.default,
 overrides: [
    {
      parser: require.resolve("@typescript-eslint/parser"),
      plugins: ["@typescript-eslint/eslint-plugin"],
      files: ["**/*.{ts,tsx}"],
      rules: import_recommended.typescript
    },
    {
      settings: {
        jest: {
          version: detectJestVersion()
        }
      },
      files: ["**/*.{test,spec,unit,e2e}.{ts,tsx,js,jsx}"],
      plugins: ["jest"],
      rules: import_recommended.jest
    }
 ],

其中,import_recommended.typescript 只有一些ts相关的验证,但是import_recommended.default 和 eslintrc.js 中的 规则也应用到了ts,tsx 文件上;也就是overrides是继承了上层rules;

参考链接

ESLint 的 parser 是个什么东西

待写

babel/eslint-parser 解析的 estree 可以实现 ts-eslint 的rules么?个人觉得是可以的,因为在babel/eslint-parser 的文档写的是为了避免重复校验,所以不再支持ts 的检查;只要ast没有丢失类型信息,应该也能完成这些rule;