pre-commit钩子TSLint提示文件不存在如何修复?Angular子目录Husky场景
问题根因与修复方案
根因分析
- Windows环境下的跨shell参数解析兼容问题:你使用的Git Bash等类Unix shell与Windows原生Node.js的参数传递逻辑存在差异,批量传递空格分隔的多个文件路径时,所有路径被错误拼接为单个参数传入
ng lint。Angular CLI会将首个非选项参数识别为项目名,因此抛出对应路径的项目不存在的错误。 - 原有脚本的参数传递不符合Angular CLI的多值参数要求:Angular CLI使用yargs做参数解析,多值参数批量传递时如果没有做分隔符适配,就会出现识别失败。而你修改为逐个调用时,每次仅传入单个路径,不会触发解析异常。
彻底修复方案
方案1:修改现有shell脚本(无需额外依赖)
将脚本shebang改为bash以支持更完善的字符串处理,调整husky.sh加载顺序,用数组存储变更文件避免路径解析问题:
#!/bin/bash # 提前加载husky上下文 . "$(dirname "$0")/_/husky.sh" changed_files=$(git diff --cached --diff-filter=d --name-only | grep .ts$ | grep ^frontend | sed "s%^frontend/%%g") if [ -n "$changed_files" ]; then cd frontend || exit 1 # 转换为数组传递参数,避免空格/解析问题 readarray -t files_arr <<< "$changed_files" npx ng lint --files "${files_arr[@]}" fi
方案2:使用lint-staged(推荐,跨平台适配更稳定)
lint-staged是专门针对Git暂存文件执行lint的工具,会自动处理路径解析、参数传递的问题,无需手动写git diff逻辑:
- 进入frontend目录安装依赖:
npm install lint-staged --save-dev - 在frontend/package.json中新增配置:
{ "lint-staged": { "*.ts": ["ng lint --files"] } }
- 将pre-commit钩子简化为:
#!/bin/sh . "$(dirname "$0")/_/husky.sh" cd frontend && npx lint-staged
该方案还可以自动支持带空格的文件名、多后缀文件匹配等场景,后续维护成本更低。
注意:如果你的Angular项目是多项目工作区,需要在
ng lint后面加上对应的项目名,比如ng lint my-project --files,否则也可能出现路径识别异常。
内容的提问来源于stack exchange,提问作者Apollo
相关产品推荐
相关产品推荐

