引言
在现代前端开发中,代码质量检查工具已经成为开发流程中不可或缺的一部分。lint-staged
作为 Git hooks 中的明星工具,能够在提交代码前自动运行各种检查工具。然而,很多开发者在使用过程中遇到了一个常见问题:为什么我的自定义脚本在 lint-staged 中运行了,但是看不到输出?
本文将深入解析 lint-staged
的 --verbose
选项,以及如何正确配置和使用它来解决输出显示问题。
问题背景
常见的困扰
假设你有一个自定义的循环依赖检查脚本:
javascript
// scripts/check-circular-deps.js
console.log('🔍 检查循环依赖...');
// ... 执行检查逻辑
console.log('✅ 循环依赖检查完成');
在 .lintstagedrc.json
中配置:
json
{
"src/**/*.{js,ts,vue}": ["node scripts/check-circular-deps.js"]
}
当你运行 git commit
时,可能会看到这样的输出:
erlang
✔ Backed up original state in git stash
✔ Running tasks for staged files...
✔ Applying modifications from tasks...
✔ Cleaning up temporary files...
问题:你的脚本明明运行了,但是看不到任何输出!这让人困惑,不知道脚本是否真的执行了,或者执行结果如何。
lint-staged 的默认行为
为什么看不到输出?
lint-staged
的默认行为是:
- 静默执行:对于成功执行的命令,默认不显示输出
- 只显示错误:只有当命令失败(退出码非0)时,才会显示错误信息
- 性能优化:减少不必要的输出,保持界面简洁
这种设计有其合理性:
- 避免输出过多信息干扰开发者
- 提高执行速度
- 保持 Git hooks 的简洁性
实际执行流程
graph TD
A[git commit] --> B[husky pre-commit hook]
B --> C[lint-staged]
C --> D{命令执行}
D -->|成功| E[静默完成]
D -->|失败| F[显示错误输出]
E --> G[继续提交]
F --> H[阻止提交]
--verbose 选项详解
什么是 --verbose?
--verbose
是 lint-staged
提供的一个命令行选项,用于显示详细的执行信息。
启用方式
方法1:在 package.json 中配置
json
{
"scripts": {
"lint-staged": "lint-staged --verbose"
}
}
方法2:在命令行中直接使用
bash
npx lint-staged --verbose
# 或
pnpm lint-staged --verbose
方法3:在 husky 配置中指定
bash
# .husky/pre-commit
pnpm lint-staged --verbose
verbose 模式下的输出
启用 --verbose
后,你会看到详细的执行信息:
bash
✔ Backed up original state in git stash (abc123)
✔ Running tasks for staged files...
✔ Applying modifications from tasks...
✔ Cleaning up temporary files...
→ eslint --config eslint.config.js:
/Users/project/src/test-file.ts
1:1 warning Unexpected console statement no-console
✖ 1 problem (0 errors, 1 warning)
→ prettier --write:
src/test-file.ts 82ms (unchanged)
→ node scripts/check-circular-deps.js:
🔍 检查循环依赖...
warn no-circular: src/pages/checkout/helpers/checkPassengerSelectRule.ts →
src/pages/checkout/constants.ts →
src/pages/checkout/helpers/index.ts →
src/pages/checkout/helpers/checkPassengerSelectRule.ts
x 21 dependency violations (0 errors, 21 warnings). 2262 modules, 4591 dependencies cruised.
✅ 循环依赖检查完成
实际应用案例
案例1:循环依赖检查
在我们的项目中,我们使用 dependency-cruiser
来检查循环依赖:
javascript
// scripts/check-circular-deps.js
import { execSync } from 'child_process';
console.log('🔍 检查循环依赖...');
try {
const output = execSync('npx depcruise src --config .dependency-cruiser.cjs', {
encoding: 'utf8',
cwd: process.cwd(),
});
console.log(output);
console.log('✅ 循环依赖检查完成');
process.exit(0);
} catch (error) {
console.log('⚠️ 发现循环依赖警告,请检查上述输出');
console.error(error.stdout || error.message);
process.exit(0);
}
配置前(看不到输出):
json
{
"src/**/*.{js,ts,vue}": ["node scripts/check-circular-deps.js"]
}
配置后(可以看到详细输出):
json
{
"*.{js,ts,vue}": [
"eslint --config eslint.config.js",
"prettier --write",
"node scripts/check-circular-deps.js"
]
}
配合 package.json
中的 --verbose
选项:
json
{
"scripts": {
"lint-staged": "lint-staged --verbose"
}
}
案例2:自定义代码质量检查
javascript
// scripts/custom-check.js
console.log('🔍 执行自定义检查...');
// 检查文件大小
const fs = require('fs');
const files = process.argv.slice(2);
files.forEach(file => {
const stats = fs.statSync(file);
const sizeInKB = Math.round(stats.size / 1024);
if (sizeInKB > 100) {
console.log(`⚠️ ${file} 文件过大: ${sizeInKB}KB`);
} else {
console.log(`✅ ${file} 文件大小正常: ${sizeInKB}KB`);
}
});
console.log('✅ 自定义检查完成');
最佳实践
1. 何时使用 --verbose
推荐使用场景:
- 开发阶段调试 lint-staged 配置
- 需要查看自定义脚本的执行结果
- 团队协作中需要了解代码检查详情
- CI/CD 环境中需要详细日志
不推荐使用场景:
- 生产环境的 Git hooks
- 对性能要求极高的场景
- 输出信息过于敏感的环境
2. 配置建议
开发环境配置
json
{
"scripts": {
"lint-staged": "lint-staged --verbose",
"lint-staged:prod": "lint-staged"
}
}
条件性启用
json
{
"scripts": {
"lint-staged": "lint-staged ${DEBUG:+--verbose}"
}
}
使用时:
bash
DEBUG=1 pnpm lint-staged # 启用 verbose
pnpm lint-staged # 正常模式
3. 脚本编写建议
确保输出可见性
javascript
// 好的做法
console.log('开始执行检查...');
console.log('检查结果:', result);
console.log('检查完成');
// 避免的做法
console.log('检查完成'); // 只有一行输出,容易被忽略
使用适当的退出码
javascript
// 成功但不阻止提交
process.exit(0);
// 失败并阻止提交
process.exit(1);
性能考虑
verbose 模式的影响
- 输出处理:需要处理更多的输出信息
- 内存使用:缓存更多的执行结果
- 执行时间:略微增加执行时间
优化建议
javascript
// 优化脚本输出
const isVerbose = process.env.VERBOSE === 'true';
if (isVerbose) {
console.log('详细执行信息...');
} else {
console.log('执行中...');
}
故障排除
常见问题
1. 仍然看不到输出
可能原因:
- 脚本没有正确执行
- 输出被重定向
- 脚本内部错误
解决方案:
bash
# 直接测试脚本
node scripts/check-circular-deps.js
# 测试 lint-staged 配置
npx lint-staged --verbose --dry-run
2. 输出格式混乱
解决方案:
javascript
// 使用 console.error 确保输出到 stderr
console.error('错误信息');
// 使用 console.log 输出到 stdout
console.log('正常信息');
3. 性能问题
解决方案:
json
{
"*.{js,ts,vue}": [
"eslint --config eslint.config.js",
"prettier --write"
],
"src/**/*.{js,ts,vue}": [
"node scripts/check-circular-deps.js"
]
}
总结
lint-staged
的 --verbose
选项是解决输出显示问题的关键工具。通过合理配置和使用,我们可以:
- 提高开发体验:清楚了解代码检查的执行情况
- 便于调试:快速定位配置和脚本问题
- 增强透明度:让团队成员了解代码质量检查的详细过程
记住,--verbose
是一个强大的调试工具,但在生产环境中要谨慎使用,避免输出过多信息影响性能。