eslint匹配规则速通

eslint匹配规则速通

匹配规则

eslint.config.js 里,"当前文件" 到底会被哪一个(或哪几个)配置对象命中,是按下述流程逐条计算的。 只要记住一句话:

ESLint 会把文件路径依次跟每个配置对象的 files/ignores 做 glob 匹配,命中且未被忽略的就生效;多个对象都命中就层层合并。

下面把"匹配"这件事拆成 5 个具体问题,一次性讲透。


  1. 拿谁来匹配? 文件在磁盘里的绝对路径 (Windows 带盘符,Unix 以 / 开头)。 例: /home/me/proj/src/utils/is-empty.js D:\repo\src\utils\is-empty.js

  2. 跟谁匹配? 每个配置对象里可能出现的两组 glob 模式:

    • files 数组 ------ 白名单
    • ignores 数组 ------ 黑名单(支持 ! 否定)
  3. 匹配顺序(级联) 对每一个配置对象:

    1. 若对象没有 files,视为 files:["**/*"](全选)。
    2. 拿文件路径去跟 files 里每一项做 minimatch(类 .gitignore 语法)。
      • 只要有一项命中就认为该对象"适用于"此文件。
    3. 若对象还有 ignores,再跟这些模式比对:
      • 命中任何 ignores立即把该对象排除,不再参与后续合并。
      • 支持否定写法 "!xxx",可再把文件"捞回来"。
    4. 全局忽略规则(对象里只有 ignores,没有 files 等其他键)会在所有对象之前先算一次,原理相同。
  4. 合并结果 经过上面筛选后,可能 0 ~ N 个对象对当前文件生效。

    • 0 个 → ESLint 报错 "No configuration provided for ..."
    • ≥1 个 → 按数组顺序浅合并 (靠后的覆盖靠前的): languageOptions/linterOptions/plugins/settings 递归合并; rules 直接覆盖同名键。
  5. 快速验证 命令行看一眼到底哪条配置命中:

    bash 复制代码
    npx eslint --inspect-config src/utils/is-empty.js

    会打印出最终合并后的完整配置以及"来自哪几个对象",调试神器。

js 复制代码
export default [
  {                           // 对象 A
    ignores: ["**/*.config.js"]   // 全局忽略
  },
  {                           // 对象 B
    files: ["src/**/*.js"],
    ignores: ["**/*.test.js"],
    rules: { semi: "warn" }
  },
  {                           // 对象 C
    files: ["**/*.test.js"],
    rules: { semi: "off" }
  }
]

现在 lint 文件 /proj/src/utils/is-empty.js

  1. 全局忽略 A 先算 ------ 文件名不是 *.config.js未被忽略,继续。
  2. 对象 B:files 命中 src/**/*.js,且不在 ignores 里 → 生效
  3. 对象 C:files 命中 **/*.test.js,但当前文件不是测试 → 跳过

最终只有 B 生效,semi: "warn"

再把 /proj/src/utils/is-empty.test.js 走一遍:

  1. 全局忽略 A 同上,未忽略。
  2. 对象 B:虽然命中 src/**/*.js,但紧接着被 **/*.test.js 忽略 → 对象 B 被排除
  3. 对象 C:命中 **/*.test.js生效semi: "off"

合并规则

flat Config 的"合并"并不是深度合并(deep merge),而是按数组顺序、一级一级地"覆盖 + 累加",规则非常干脆:

  1. 数组顺序 = 优先级 后出现的 config 对象如果和前面的同字段同名 ,就整值覆盖;不同名就累加。
  2. 命中范围(files / ignores)独立判断 对单个文件来说,ESLint 会把所有路径命中 的 config 对象收集起来,再按顺序合并; 只要某一段 config 的 ignores 匹配了,这段及后面同路径的 config 就被整段跳过。
  3. 合并粒度只到"字段"一级
    • languageOptionspluginsrules 都是整对象替换,不会递归合并内部子键。
    • 想"增量"就必须把前面那段再抄一遍,或者利用展开运算符自己拼装。

看一段代码就懂

js 复制代码
export default [
  {                                                    // ①
    files: ['**/*.ts'],
    languageOptions: { parser: ts.parser, ecmaVersion: 2022 },
    rules: { '@typescript-eslint/no-explicit-any': 'warn', 'no-console': 'off' }
  },
  {                                                    // ②
    files: ['**/*.ts'],
    rules: { 'no-console': 'error' }                   // 整对象覆盖,结果只剩 no-console:error
  }
];

对任意 .ts 文件:

  • 先收集 ① → 再收集 ②
  • ② 的 rules 是全新对象,直接把 ① 的 rules 整份替换掉;languageOptions 保留 ① 的,因为 ② 没写。

最终生效的只有:

js 复制代码
languageOptions: { parser: ts.parser, ecmaVersion: 2022 }
rules: { 'no-console': 'error' }

@typescript-eslint/no-explicit-any 这条规则被"覆盖没"了------不会自动保留

相关推荐
GreenTea9 小时前
一文搞懂Harness Engineering与Meta-Harness
前端·人工智能·后端
killerbasd11 小时前
牧苏苏传 我不装了 4/7
前端·javascript·vue.js
吴声子夜歌11 小时前
ES6——二进制数组详解
前端·ecmascript·es6
码事漫谈11 小时前
手把手带你部署本地模型,让你Token自由(小白专属)
前端·后端
ZC跨境爬虫11 小时前
【爬虫实战对比】Requests vs Scrapy 笔趣阁小说爬虫,从单线程到高效并发的全方位升级
前端·爬虫·scrapy·html
爱上好庆祝11 小时前
svg图片
前端·css·学习·html·css3
王夏奇12 小时前
python中的__all__ 具体用法
java·前端·python
大家的林语冰12 小时前
《前端周刊》尤大开源 Vite+ 全家桶,前端工业革命启动;尤大爆料 Void 云服务新产品,Vite 进军全栈开发;ECMA 源码映射规范......
前端·javascript·vue.js
jiayong2313 小时前
第 8 课:开始引入组合式函数
前端·javascript·学习
田八13 小时前
聊聊AI的发展史,AI的爆发并不是偶然
前端·人工智能·程序员