自定义Git pre-commit钩子中lint-staged未正常检测代码问题求助
我之前也碰到过一模一样的情况——钩子能正常触发、脚本没报错,但就是抓不住本地直接运行lint-staged能发现的代码问题。结合你的场景和脚本内容,大概率是这几个原因导致的,咱们一步步排查:
1. Git暂存区上下文未正确传递
当你切换到server目录执行npx lint-staged时,lint-staged可能没拿到项目根目录的Git暂存区状态(毕竟Git仓库根目录在root_dir,不是server)。这会导致它误以为没有需要检测的暂存文件,直接“空跑”结束。
解决办法:
修改脚本,要么切换到项目根目录后指定lint-staged的工作目录为server,要么在server目录下强制指定Git工作区路径:
方案一(切换到根目录执行):
#!/bin/bash script_path=$(readlink -f "$0") hooks_dir=$(dirname "$script_path") root_dir=$(dirname "$hooks_dir") echo "Running pre-commit" cd "${root_dir}" && npx lint-staged --cwd server
方案二(在server目录指定Git工作区):
#!/bin/bash script_path=$(readlink -f "$0") hooks_dir=$(dirname "$script_path") root_dir=$(dirname "$hooks_dir") echo "Running pre-commit" cd "${root_dir}/server" && GIT_WORKING_DIR="${root_dir}" npx lint-staged
2. lint-staged找不到正确的配置文件
如果你的lint-staged配置写在项目根目录的.lintstagedrc或package.json里,切换到server目录后,它可能会默认读取server/package.json里的配置(如果没有就直接用默认规则,而默认规则可能不匹配你的代码检查需求)。
解决办法:
显式指定配置文件路径,确保lint-staged用的是你预期的规则:
cd "${root_dir}/server" && npx lint-staged --config "${root_dir}/.lintstagedrc"
如果配置在server/package.json里,也可以显式指定避免歧义:
cd "${root_dir}/server" && npx lint-staged --config package.json
3. npx缓存导致版本不一致
有时候npx会调用缓存的lint-staged版本,和你本地server/node_modules里安装的版本不一样——版本差异可能导致规则执行逻辑不同,出现“本地能检测出问题,钩子不行”的情况。
解决办法:
直接调用本地安装的lint-staged二进制文件,跳过npx缓存:
cd "${root_dir}/server" && ./node_modules/.bin/lint-staged
4. 钩子运行的环境变量异常
Git钩子的运行环境和你终端的环境变量可能不一样(比如PATH里的Node路径不同),导致lint-staged依赖的检查工具(如ESLint、Prettier)无法正常执行。
排查方法:
在脚本里添加环境变量打印,对比终端输出:
echo "Hook PATH: $PATH" echo "Hook Node path: $(which node)" echo "Terminal Node path: $(which node)" # 先在终端执行这句记下来结果
如果路径不一致,就手动指定Node和工具的绝对路径,比如:
cd "${root_dir}/server" && /usr/local/bin/node ./node_modules/.bin/lint-staged
优先试试第一个方案,这是最常见的触发原因,一般改完就能正常检测代码问题了。
内容的提问来源于stack exchange,提问作者natikos




