lint-staged 忽略指定文件的配置方法
场景
git 提交时使用 lint-staged 对代码进行 lint 检查,想要忽略某个指定的文件
这个需求在用了自动导入插件的项目里特别常见。unplugin-auto-import 会生成 auto-imports.d.ts,unplugin-vue-components 会生成 components.d.ts,这些文件是工具吐出来的,格式不受我控制,每次改动都被 eslint 和 prettier 拦下来报一堆错。它们本身也不需要人来维护,跑 lint 纯属浪费时间。
麻烦的是 .eslintignore 在这里不管用。lint-staged 的工作方式是拿到暂存区的文件列表,按 glob 匹配后把文件路径当参数拼到命令后面执行。当 eslint 被显式传入了文件路径时,它会认为这是用户明确指定要检查的文件,.eslintignore 里的规则就被覆盖了,只会打印一条 File ignored because of a matching ignore pattern 的警告——如果配了 --max-warnings 0,这条警告直接让命令失败。所以要真正跳过,得在 lint-staged 这一层就把文件从列表里剔掉。
解决方法
降低 lint-staged 版本至 8.1.5
8.x 时代的 lint-staged 配置里有一个顶层的 ignore 字段,接收一组 glob,匹配到的文件不会进入任务列表。这个字段在后来的版本被移除了,官方的思路是让用户在 glob 里自己写排除逻辑,或者在命令前面加一层过滤脚本。所以如果你能接受锁版本,降到 8.1.5 是最直接的办法。
注意 8.x 的配置结构和新版不一样:任务要写在 linters 对象里,而不是像新版那样直接把 glob 作为顶层的 key。
配置如下
module.exports = {
linters: {
'*.{js,jsx,ts,tsx}': [
'eslint --fix',
'eslint --ignore-path .gitignore --max-warnings 0',
'prettier --write',
],
'*.vue': [
'eslint --fix',
'eslint --ignore-path .gitignore --max-warnings 0',
'stylelint --fix',
'prettier --write',
],
'*.{scss,less,styl,html}': ['stylelint --fix', 'prettier --write'],
},
ignore: ['*auto-imports.d.ts'],
};
不降版本的做法
锁在老版本终究不是长久之计,新版有几个替代方案。
一是在 glob 里用取反语法把文件排除掉。lint-staged 用 micromatch 做匹配,支持 !(...) 这种否定模式,比如把 *.{js,ts} 换成排除特定文件的写法。这个方案的坑是 glob 语法容易写错,而且默认只匹配文件名不匹配路径,调起来比较费劲。
二是把命令换成函数。新版配置支持给某个 glob 指定一个函数,函数拿到匹配的文件数组,返回要执行的命令字符串数组。这样过滤逻辑就是普通 JS,想怎么筛都行:
module.exports = {
'*.{js,jsx,ts,tsx}': files => {
const filtered = files.filter(f => !f.endsWith('auto-imports.d.ts'));
if (filtered.length === 0) return [];
return [
`eslint --fix ${filtered.join(' ')}`,
`prettier --write ${filtered.join(' ')}`,
];
},
};
这里返回空数组很重要。如果过滤后没有文件剩下,还硬拼一条不带文件参数的 eslint --fix,eslint 会去检查整个项目,慢且可能报出一堆无关的错。
三是给 eslint 加 --no-error-on-unmatched-pattern,或者干脆去掉 --max-warnings 0,让那条 ignore 警告不至于中断提交。这算是绕过而不是解决,但对付单个恼人的文件够用了。

还没有留言,来发表第一条吧~