You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

lint-staged检测范围异常:未暂存文件导致提交失败

Monorepo下lint-staged结合Yarn脚本只检查暂存文件的解决方案

问题背景

在monorepo的packageA里有两个带ESLint错误的JS文件,修复并暂存其中一个后,执行提交却因为未暂存的另一个文件触发lint失败,导致提交被拦截。

环境信息

目录结构

.lintstagedrc.mjs
├── packages
│   ├── packageA
│   │   ├── .lintstagedrc.mjs
│   │   └── components
│   │       ├── compA.js
│   │       └── compB.js
│   ├── packageB
│   │   └── .lintstagedrc.mjs
│   └── packageC
│       └── .lintstagedrc.mjs

关键配置

  • 根目录.lintstagedrc.mjs:
    export default {
      '*.js': 'eslint --fix'
    };
    
  • 子包.lintstagedrc.mjs:
    export default {
      '*.js': 'yarn lint:js',
      '*.hbs': 'yarn lint:hbs'
    };
    
  • 子包package.json脚本:
    "scripts": {
        "lint:js": "eslint . --cache",
        "lint:hbs": "handlebars-lint ."
    }
    
  • Husky预提交钩子.husky/pre-commit:
    npx lint-staged
    

问题原因

lint-staged已经正确识别并传入了暂存的compA.js文件,但yarn lint:js里的eslint . --cache会强制扫描整个当前目录,完全忽略了传入的文件列表,导致未暂存的compB.js中的错误被检测到,触发提交失败。你之前尝试的eslint ${@:-.} --cache未生效,是因为Yarn对脚本参数的解析逻辑和原生bash不同。

可行解决方案

方案1:修改Yarn脚本,适配参数传递

通过bash显式包裹脚本逻辑,确保参数能被正确解析。修改子包package.json的脚本:

"scripts": {
    "lint:js": "bash -c 'eslint ${@:-.} --cache' --",
    "lint:hbs": "bash -c 'handlebars-lint ${@:-.}' --"
}
  • 当lint-staged传入暂存文件列表时,脚本会用这些文件作为eslint的检查目标;
  • 单独执行yarn lint:js时,默认检查当前目录下所有文件,保留原有功能。

如果是Yarn 2及以上版本,也可以用更简洁的写法:

"scripts": {
    "lint:js": "eslint $@ --cache || eslint . --cache",
    "lint:hbs": "handlebars-lint $@ || handlebars-lint ."
}

逻辑是先尝试使用传入的参数,没有参数时再默认检查当前目录。

方案2:调整lint-staged配置,显式传递文件

在子包的.lintstagedrc.mjs中,直接将暂存文件列表作为参数传给Yarn脚本:

export default {
  '*.js': (files) => `yarn lint:js ${files.map(f => `"${f}"`).join(' ')}`,
  '*.hbs': (files) => `yarn lint:hbs ${files.map(f => `"${f}"`).join(' ')}`
};

同时修改子包package.json的脚本为:

"scripts": {
    "lint:js": "eslint $@ --cache",
    "lint:hbs": "handlebars-lint $@"
}

这种方式让lint-staged主动把文件列表传递给脚本,脚本直接用$@接收参数,确保只检查指定文件。

验证方法

修改完成后,运行调试命令:

npx lint-staged --debug

可以看到执行的命令会带上暂存的文件路径,比如yarn lint:js "packages/packageA/components/compA.js",此时ESLint只会检查这个文件,不会触发未暂存文件的错误,提交即可成功。同时单独执行yarn lint:js仍会扫描整个目录,不影响日常lint检查。

内容的提问来源于stack exchange,提问作者gtb104

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 21:35:12