ESLint 之解析包名

ESLint 配置文件中 extends 的写法多种多样,那么 ESLint 是怎么根据不同的写法找到正确的包呢?

extends 分类

假设有这样一个 .eslintrc.js

module.exports = {
  extends: [
    'eslint:recommended',
    'eslint-config-react',
    'react',
    './ireneRule.js',
    'prettier/@typescript-eslint',
    'plugin:@typescript-eslint/recommended',
    'plugin:@typescript-eslint/eslint-plugin/recommended',
    'plugin:@typescript-eslint/test/recommended', // 为了测试,杜撰的一个包
    'plugin:@typescript-eslint/eslint-plugin-irene/recommended', // 为了测试,杜撰的一个包
    'plugin:prettier/recommended',
  ],
}

extends 中有三类写法:

eslint: 开头,加载 ESLint 内置规则

  • 如果是 eslint:recommended,加载 ESLint 推荐的规则;

  • 如果是 eslint:all,加载 ESLint 所有的规则;

plugin: 开头

  • 首先分离出 pluginName,它就是 plugin: 和最后一个 / 的之间部分;有如下几种情况:

    • plugin:@typescript-eslint/recommended 的 pluginName 是 @typescript-eslint

    • plugin:@typescript-eslint/eslint-plugin/recommended 的 pluginName 是 @typescript-eslint/eslint-plugin

    • plugin:@typescript-eslint/test/recommended 的 pluginName 是 @typescript-eslint/test

    • plugin:@typescript-eslint/eslint-plugin-irene/recommended 的 pluginName 是 @typescript-eslint/eslint-plugin-irene

    • plugin:prettier/recommended 的 pluginName 是 prettier

  • 然后根据 pluginName 得到标准化的包名;

    • 如果 pluginName 以 @ 开头,说明使用的是 scoped modules;有如下几种情况:

      • pluginName 是 @scopeName 或 @scopeName/eslint-plugin,对应的包名是 @scopeName/eslint-plugin;

        • @typescript-eslint 对应的是 @typescript-eslint/eslint-plugin

        • @typescript-eslint/eslint-plugin 对应的是 @typescript-eslint/eslint-plugin

      • pluginName 是 @scopeName/xxx,且 xxx 不以 eslint-plugin 开头,对应的包名是 @scopeName/eslint-plugin-xxx;

        • @typescript-eslint/test 对应的是 @typescript-eslint/eslint-plugin-test

      • pluginName 是 @scopeName/eslint-plugin-xxx,对应的包名是 @scopeName/eslint-plugin-xxx;

        • @typescript-eslint/eslint-plugin-irene 对应的是 @typescript-eslint/eslint-plugin-irene

    • 如果 pluginName 不以 eslint-plugin- 开头,对应的包名是 eslint-plugin-xxx;例如:prettier 对应的是 eslint-plugin-prettier

其他

  • 一个本地路径,指向本地的 ESLint 配置,例如:./ireneRule.js

  • 以 . 开头,这是为了兼容之前的版本,不过多解释;

  • 根据 extendName 得到标准化的包名,这一步与 plugin 相同;

    • 如果 extendName 以 @ 开头,说明使用的是 scoped modules;有如下几种情况:

      • extendName 是 @scopeName 或 @scopeName/eslint-config,对应的包名是 @scopeName/eslint-config;

      • extendName 是 @scopeName/xxx,且 xxx 不以 eslint-config 开头,对应的包名是 @scopeName/eslint-config-xxx;

      • extendName 是 @scopeName/eslint-config-xxx,对应的包名是 @scopeName/eslint-config-xxx;

    • 如果 extendName 不以 eslint-config- 开头,对应的包名是 eslint-config-xxx;例如:react 对应的是 eslint-config-react

ESLint 源码

解析 extends 得到包名主要涉及的源码如下:

eslint/lib/cli-engine/config-array-factory.js

如何 debug ESLint?

  • 在 node_modules 中的 ESLint 源码打上断点;

  • 项目根目录下运行如下命令,其中 -c .eslintrc.js 指定 ESLint 配置文件,./src/storage/testEslint.ts 是待校验的文件;

  • 打开 chrome://inspect/#devices,点击 inspect

  • 然后就可在 Chrome 或 VSCode 中调试 ESLint 源码;

参考

英文:shareable-configsarrow-up-right

中文:shareable-configsarrow-up-right

Last updated