前端工程化必备:lint-staged全解析
简单说:lint-staged 是一个 “只对 Git 暂存区文件执行命令” 的工具 🛠️● 「暂存区文件」:就是你执行git add后,准备提交的那些文件(没 add 的文件它不管);● 「核心作用」:提交代码前,自动对这些修改后的文件做 lint 检查(如 ESLint)、格式美化(如 Prettier),有错误就拦截提交,避免不规范代码进仓库;● 「为啥必须用」:如果直接执行eslint
一、先搞懂:lint-staged 到底是个啥?
简单说:lint-staged 是一个 “只对 Git 暂存区文件执行命令” 的工具 🛠️
● 「暂存区文件」:就是你执行git add后,准备提交的那些文件(没 add 的文件它不管);
● 「核心作用」:提交代码前,自动对这些修改后的文件做 lint 检查(如 ESLint)、格式美化(如 Prettier),有错误就拦截提交,避免不规范代码进仓库;
● 「为啥必须用」:如果直接执行eslint .,会检测整个项目的所有文件(哪怕没修改),Monorepo 项目动辄十几个包,全量检测要等半天!而 lint-staged 只盯你改的文件,速度快到飞起~
举个🌰:你改了packages/ui/Button.tsx并git add,lint-staged 只会对这个文件执行 ESLint+Prettier,其他没动的文件完全不碰,效率直接拉满!
官方定义:lint-staged runs linters against staged git files and don’t let
💩 slip into your codebase!(不让垃圾代码溜进代码库~)
二、核心优势:为啥 Monorepo 项目离不开它?
- 速度快:只检测暂存区文件,比全量 lint 快 10 倍 +,大型项目体感差距超明显;
- 不折腾:自动修复格式错误(如缩进、引号),不用手动改,省时间;
- 强制规范:有无法修复的错误(如语法错误)直接拦截提交,确保代码库整洁;
- 灵活配置:支持多文件类型(JS/TS/JSON/MD)、多命令组合,适配 Monorepo 多包结构。
三、实战教程:3 步搞定 lint-staged 配置(Monorepo 专属)
以 pnpm workspace 项目为例,全程复制命令就行,不用懂原理~
3.1 第一步:安装依赖(已装过的跳过)
在项目根目录执行,把 lint-staged 和配套工具一起装了:
若用pnpm(推荐)
pnpm add -Dw lint-staged eslint prettier eslint-config-prettier eslint-plugin-prettier
若用yarn
yarn add -D lint-staged eslint prettier eslint-config-prettier eslint-plugin-prettier
鱼姐小贴士:-Dw是 pnpm 专属,意思是 “作为开发依赖安装到根目录”,Monorepo 项目统一在根目录管理依赖,子包不用单独装~
3.2 第二步:配置 lint-staged(关键!)
有 2 种配置方式,选一种就行,推荐第一种(直接写在 package.json 里,简单方便):
方式 1:在 package.json 中配置(推荐)
打开根目录的package.json,添加lint-staged字段,按文件类型指定要执行的命令:
{
"lint-staged": {
// 1. JS/TS/JSX/TSX文件:先eslint自动修复,再prettier格式化
"packages/**/*.{js,jsx,ts,tsx}": [
"eslint --fix", // 自动修复可修复的lint错误(如未使用变量、引号不统一)
"prettier --write" // 格式化代码(如缩进、分号)
],
// 2. JSON/MD文件:只做prettier格式化
"packages/**/*.{json,md}": [
"prettier --write"
],
// 3. CSS/SCSS文件:可选,需要装stylelint
"packages/**/*.{css,scss}": [
"stylelint --fix",
"prettier --write"
]
}
}
方式 2:单独创建配置文件(适合复杂配置)
在根目录创建.lintstagedrc.js文件,内容如下:
module.exports = {
"packages/**/*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
"packages/**/*.{json,md}": ["prettier --write"],
"packages/**/*.{css,scss}": ["stylelint --fix", "prettier --write"]
};
Monorepo 专属优化:按包拆分配置(可选)
如果想让不同包执行不同规则(比如 ui 包要检测 CSS,core 包不用),可以这样写:
{
"lint-staged": {
"packages/core/**/*.{js,ts}": ["eslint --fix"], // core包只做JS/TS lint
"packages/ui/**/*.{js,ts,css}": ["eslint --fix", "stylelint --fix", "prettier --write"], // ui包多检测CSS
"packages/web-app/**/*.{js,tsx}": ["eslint --fix", "prettier --write"] // 应用包检测TSX
}
}
3.3 第三步:关联 Husky,提交时自动触发
lint-staged 不会自己跑,需要配合 Husky 的pre-commit钩子(提交前触发),之前的教程里已经配置过,这里再补一遍关键步骤:
1. 若未初始化Husky,先执行(已初始化的跳过)
npx husky install
pnpm pkg set scripts.prepare=“husky install” # 安装依赖后自动启用Husky
2. 添加pre-commit钩子,触发lint-staged
npx husky add .husky/pre-commit ‘npx lint-staged’
原理:当你执行git commit(或pnpm run commit)时,Husky 会先触发pre-commit钩子,执行npx lint-staged,对暂存区文件做校验,没问题才允许提交~
四、怎么用?日常开发只需要 3 步!
配置好后,平时开发完全不用管 lint-staged,跟着正常流程走就行:
步骤 1:修改文件并暂存
比如修改了ui包的Button组件
git add packages/ui/src/Button.tsx
步骤 2:执行提交(和平时一样)
用之前配置的交互式提交
pnpm run commit
或直接用git commit(也会触发)
git commit -m "feat(ui): 优化Button组件样式"
步骤 3:观察结果
● ✅ 若代码没问题:直接提交成功,不用任何操作;
● ✅ 若有可修复错误(如格式问题):lint-staged 自动修复,然后提交成功;
● ❌ 若有无法修复的错误(如语法错误、未定义变量):提交被拦截,终端会显示错误信息,按提示修改后重新提交。
终端成功示例:
✔ Preparing lint-staged...
✔ Running tasks for staged files...
✔ Applying modifications from tasks...
[feature/ui-button 1234567] feat(ui): 优化Button组件样式
1 file changed, 5 insertions(+), 3 deletions(-)
终端错误示例(需修复):
✖ eslint --fix found some errors. Please fix them and try committing again.
packages/ui/src/Button.tsx
10:5 error 'unusedVar' is assigned a value but never used no-unused-vars
解决方案:删除未使用的变量unusedVar,重新git add并提交~
五、高级技巧:让 lint-staged 更好用
技巧 1:添加调试模式,排查问题
如果 lint-staged 不生效,或想看看它检测了哪些文件,加–debug参数:
npx lint-staged --debug
终端会输出详细日志,比如哪些文件被匹配、执行了什么命令,方便排查配置问题。
技巧 2:禁用并发执行(解决冲突)
默认情况下,lint-staged 会并行执行多个任务(比如同时处理 JS 和 CSS 文件),如果出现冲突,可设置为串行执行:
{
"lint-staged": {
"concurrent": false, // 禁用并发,按顺序执行任务
"packages/**/*.{js,ts}": ["eslint --fix"],
"packages/**/*.{css,scss}": ["stylelint --fix"]
}
}
技巧 3:允许空提交(特殊场景)
默认情况下,如果 lint-staged 自动修复后,暂存区文件为空(比如只改了格式,修复后和原文件一致),会拦截提交。如果需要允许空提交,加–allow-empty参数:
修改Husky的pre-commit钩子
npx husky add .husky/pre-commit 'npx lint-staged --allow-empty'
技巧 4:在 CI/CD 中使用(如 GitHub Actions)
之前的 CI/CD 配置里已经用到了,直接在 workflows 文件中执行:
- name: 执行lint
run: npx lint-staged # 或 pnpm lint-staged(需在package.json配置脚本)
这样 PR 提交时,CI 会自动执行 lint-staged,确保远程分支代码也符合规范~
六、常见问题:鱼姐踩过的坑(必看)
坑 1:lint-staged 不生效,提交时没反应
● 原因 1:没关联 Husky 的 pre-commit 钩子,或钩子命令写错;
● 解决方案:重新执行npx husky add .husky/pre-commit ‘npx lint-staged’,检查.husky/pre-commit文件内容是否正确;
● 原因 2:文件没加入暂存区(没执行git add);
● 解决方案:先git add文件,再执行提交。
坑 2:Monorepo 中只检测部分包的文件
● 原因:配置的文件路径不对,没匹配到所有包;
● 解决方案:用packages//*匹配所有包的文件,而不是src//*(只匹配根目录 src)。
坑 3:prettier 和 ESLint 规则冲突(比如引号、分号)
● 原因:两者规则不一致(如 ESLint 要求双引号,Prettier 要求单引号);
● 解决方案:安装eslint-plugin-prettier,让 ESLint 继承 Prettier 规则,在.eslintrc.js中添加:
extends: [
"eslint:recommended",
"plugin:prettier/recommended" // 关键:让ESLint遵循Prettier规则
]
坑 4:执行时提示 “command not found: eslint/prettier”
● 原因:依赖没装对,或没装在根目录;
● 解决方案:在根目录重新执行安装命令(pnpm add -Dw …),确保依赖出现在根目录的node_modules中。
最后总结:lint-staged 用起来真的香!
其实 lint-staged 的核心就是 “精准打击”—— 只处理你修改的文件,既保证了代码规范,又不浪费时间,Monorepo 项目用它,提交速度能快一倍~
配置一次,终身受益,团队里不管是新手还是老鸟,都不用再操心格式问题,Code Review 时也能专心看业务逻辑,不用纠结 “缩进不对”“引号不统一” 这种琐事~
如果你的项目是 lerna 架构,或需要配置特殊规则(比如忽略某些文件、自定义命令),可以评论区告诉我你的场景,鱼姐给你定制配置!觉得有用的宝子,记得收藏 + 点赞,关注鱼姐,前端工程化踩坑不迷路~❤️
更多推荐
所有评论(0)