lint-staged logo

lint-staged

在 Git 暂存区文件上运行 linter、formatter 等代码质量工具,确保每次提交都符合代码规范。

代码质量Git暂存文件自动化检查

lint-staged 在 Git 暂存区文件上运行 linter、formatter 等代码质量工具,只对已暂存的文件执行检查,确保每次提交都符合规范,避免全量检查的性能开销。

lint-staged

在 Git 暂存区文件上运行 linter、formatter 等代码质量工具,确保每次提交都符合代码规范。

技术简介说明

lint-staged 是一个运行在 Git pre-commit 钩子中的 Node.js 工具,它只对 已暂存(staged)的文件 执行配置好的代码检查任务(如 ESLint、Prettier、Stylelint 等)。这样可以避免对整个仓库执行全量检查,大幅缩短提交前的等待时间。

lint-staged 本身不管理 Git 钩子,而是需要配合 Git 钩子管理工具(如 HuskyLefthook)一起使用。当开发者执行 git commit 时,Git 触发 pre-commit 钩子 → Husky 调用 lint-staged → lint-staged 只检查被 git add 暂存的文件 → 检查通过后提交才能成功。

这种机制实现了 Fail Fast(快速失败)原则:将代码质量问题拦截在提交阶段,而非推送到 CI 后才发现。

基本信息

项目信息
当前最新版本v17.0.8(2026年)
许可证MIT
语言/运行时Node.js(要求 ≥ 22.x)
Git 要求≥ 2.32.0
包管理器npm / pnpm / yarn
GitHub 仓库lint-staged/lint-staged
npm 包lint-staged
月下载量数百万级别(前端生态基础设施)
首次发布2016 年
维护状态积极维护中

快速上手

安装

# 使用 pnpm(推荐)
pnpm add -D lint-staged husky
 
# 使用 npm
npm install -D lint-staged husky
 
# 使用 yarn
yarn add -D lint-staged husky

初始化 Husky

# 初始化 husky,创建 .husky/ 目录
npx husky init
 
# 这会自动创建 .husky/pre-commit 文件并添加 `npx lint-staged` 命令

最小配置示例

package.json 中添加配置:

{
  "lint-staged": {
    "*.js": "eslint --fix",
    "*.{js,ts,tsx}": "prettier --write"
  }
}

或者创建独立的配置文件 .lintstagedrc.js

export default {
  '*.js': ['eslint --fix'],
  '*.{js,ts,tsx}': ['prettier --write'],
  '*.{css,scss}': ['stylelint --fix'],
}

完整最小示例

# 1. 安装依赖
pnpm add -D lint-staged husky eslint prettier
 
# 2. 初始化 husky
npx husky init
 
# 3. 确认 .husky/pre-commit 文件内容包含:
# npx lint-staged
 
# 4. 添加 lint-staged 配置到 package.json
# 5. 暂存文件并提交
git add .
git commit -m "feat: 初始化项目"
# → 此时 lint-staged 自动对暂存文件执行 eslint --fix 和 prettier --write

核心概念与架构

工作流程

开发者修改文件
       │
       ▼
  git add <files>       ← 文件进入暂存区(staging area)
       │
       ▼
  git commit
       │
       ▼
  Git 触发 pre-commit 钩子
       │
       ▼
  Husky 执行 .husky/pre-commit 脚本
       │
       ▼
  lint-staged 启动
       │
       ├─→ 1. 获取所有暂存文件列表 (git diff --cached)
       │
       ├─→ 2. 使用 glob 模式匹配暂存文件
       │     (内部使用 picomatch 库)
       │
       ├─→ 3. 对匹配的文件执行配置的命令
       │     (如 eslint --fix file1.js file2.js)
       │
       ├─→ 4. 将修改后的文件重新加入暂存区 (git add)
       │
       └─→ 5. 如果任一命令失败 → 提交被拒绝
             如果全部通过 → 提交继续

Glob 匹配规则

lint-staged 使用 picomatch(v15+ 版本)进行 glob 匹配,遵循以下规则:

  • 不含 / 的 glob:匹配任意目录下的文件名。例如 *.js 匹配 src/app.jstest/unit.js
  • / 的 glob:按完整路径匹配。例如 src/*.js 只匹配 src/ 目录下的 .js 文件
  • 支持扩展 glob:如 *.&#123;js,ts&#125; 匹配 .js.ts 文件

架构组成

模块职责
配置加载器读取 package.json.lintstagedrc.lintstagedrc.jsonlint-staged.config.js 等配置
Git 暂存文件获取调用 git diff --cached --diff-filter=ACMR --name-only 获取暂存文件列表
Glob 匹配引擎使用 picomatch 将暂存文件与配置的 glob 模式匹配
任务执行器顺序/并行执行配置的任务命令
Git 操作管理使用 git stash 暂存未暂存的变更,任务完成后恢复
输出格式化控制台输出任务执行状态和结果

核心特性

1. 仅检查暂存文件

lint-staged 只对通过 git add 暂存的文件执行检查,而非整个仓库。这让提交前检查从全量 ESLint 的 30 秒缩短到仅检查几个文件的 1-2 秒。

2. 灵活的 Glob 模式匹配

支持丰富的 glob 语法,可为不同类型的文件配置不同的检查任务:

export default {
  '*.js': 'eslint --fix',
  '*.{ts,tsx}': ['eslint --fix', 'prettier --write'],
  '*.md': 'markdownlint',
  'src/**/*.{css,scss}': 'stylelint --fix',
}

3. 函数式任务配置(v16+)

v16 引入的函数式任务,允许动态生成命令,接收匹配文件列表作为参数:

export default {
  '*.js': (files) => {
    // 根据文件数量选择不同的检查方式
    if (files.length > 100) {
      return ['eslint --fix --quiet']
    }
    return [`eslint --fix ${files.join(' ')}`]
  },
}

4. 多命令顺序执行

支持为同一 glob 模式配置多个命令,按数组顺序执行:

{
  "*.js": ["eslint --fix", "prettier --write"]
}

5. Git Stash 保护机制

lint-staged 在运行任务前会 git stash 保存未暂存的修改,任务完成后恢复。这确保了:

  • 任务只看到暂存区的内容
  • 未暂存的修改不会丢失
  • 即使任务失败,原始工作状态也能恢复

6. 自动重新暂存

任务对文件做出修改后(如 --fix--write),lint-staged 自动将修改后的文件重新加入暂存区,开发者无需手动操作。

7. 多种配置格式支持

package.json 中的 "lint-staged" 字段
.lintstagedrc(JSON)
.lintstagedrc.json
.lintstagedrc.yaml
.lintstagedrc.yml
.lintstagedrc.mjs
.lintstagedrc.js
.lintstagedrc.cjs
lint-staged.config.js
lint-staged.config.mjs
lint-staged.config.cjs

8. 详细的调试模式

使用 --debug 标志可以看到完整的执行过程,包括文件匹配、命令执行和性能计时信息:

npx lint-staged --debug

9. 并发控制

可配置任务并发数,避免同时运行过多任务导致性能问题:

export default {
  '*': 'prettier --write',
}
// 配合 --concurrent 参数控制并发
npx lint-staged --concurrent 5

10. 相对路径支持

命令中的文件路径默认使用相对于项目根目录的路径,与 ESLint、Prettier 等工具的配置兼容。

生态图

与 Husky 的配合(行业标准)

┌──────────────────────────────────────────────────────────┐
│                    Git Hooks 生态                         │
├──────────────────────────────────────────────────────────┤
│                                                          │
│  ┌─────────┐     ┌─────────┐     ┌──────────────────┐   │
│  │  Husky   │────▶│lint-staged│────▶│ ESLint/Prettier  │   │
│  │(钩子管理) │     │(文件过滤) │     │ (代码检查工具)    │   │
│  └─────────┘     └─────────┘     └──────────────────┘   │
│       │                                                    │
│       ├──▶ commitlint(提交信息规范)                       │
│       │                                                    │
│       └──▶ stylelint / markdownlint / ...                  │
│                                                          │
└──────────────────────────────────────────────────────────┘

典型配置链路

Husky (pre-commit)
   └─→ npx lint-staged
          ├─→ eslint --fix *.js
          ├─→ prettier --write *.{js,ts,tsx}
          └─→ stylelint --fix *.css

Husky (commit-msg)
   └─→ npx commitlint --edit "$1"
          └─→ 校验提交信息格式

完整生态工具链

工具角色说明
HuskyGit 钩子管理管理 pre-commitcommit-msg 等钩子
LefthookGit 钩子管理(替代)Go 编写的 Husky 替代品,更快
lint-staged暂存文件过滤执行只运行 linter 到暂存文件上
ESLintJavaScript/TypeScript 检查代码质量和风格检查
Prettier代码格式化统一代码风格
StylelintCSS/SCSS 检查样式代码质量检查
commitlint提交信息规范配合 commit-msg 钩子使用
Biome全能工具(新兴)Rust 编写的 linter + formatter
OxlintJavaScript 检查(新兴)Rust 编写的超快 linter

适用场景

1. 团队代码规范统一

在多人协作项目中,通过 lint-staged 确保每次提交都经过 ESLint 和 Prettier 处理,防止不规范的代码进入仓库。

// .lintstagedrc.js
export default {
  '*.{js,ts,tsx}': ['eslint --fix', 'prettier --write'],
}

2. 增量格式化与修复

对已有存量代码的老项目,lint-staged 允许逐步修复 —— 只格式化本次修改的文件,而不必一次性处理整个仓库。

export default {
  '*.js': ['eslint --fix --quiet'],  // --quiet 减少输出干扰
}

3. Monorepo 场景

在 pnpm workspace / Turborepo / Nx 等 Monorepo 中,lint-staged 配合工作区工具,只检查变更的包中的文件。

// 根目录 .lintstagedrc.js
export default {
  'packages/**/*.{js,ts}': ['pnpm --filter ./packages/* exec eslint --fix'],
}

4. 多语言/多类型文件项目

对同时包含 JavaScript、TypeScript、CSS、Markdown 等多种文件类型的项目,按文件类型分别配置检查工具。

export default {
  '*.{js,ts,tsx}': ['eslint --fix', 'prettier --write'],
  '*.{css,scss,less}': ['stylelint --fix', 'prettier --write'],
  '*.md': ['markdownlint', 'prettier --write'],
  '*.{json,yaml,yml}': ['prettier --write'],
}

5. CI 前的本地质量门禁

作为开发者提交代码的第一道防线,将 CI 中可能失败的检查提前到本地执行,减少 CI 资源浪费。

6. 自动化代码修复工作流

结合 --fix--write 参数,lint-staged 在提交前自动修复可自动处理的问题(如缺少分号、引号风格等)。

export default {
  '*.{js,ts}': [
    'eslint --fix --max-warnings=0',
    'prettier --write',
  ],
}

7. 安全扫描前置

对暂存的代码运行安全扫描工具,防止敏感信息泄露到 Git 历史中。

export default {
  '*': ['npx gitleaks protect --staged --verbose'],
}

开发与工程化

配置文件选型

配置方式适用场景示例
package.json "lint-staged"简单项目、配置简短&#123;"*.js": "eslint"&#125;
.lintstagedrc.js需要条件逻辑或函数式任务export default &#123; ... &#125;
lint-staged.config.js配置复杂、需要导入其他模块独立配置文件
.lintstagedrc.json纯 JSON、团队协作标准 JSON 配置

与 Husky 的完整集成

# 目录结构
├── .husky/
   ├── pre-commit       # 内容: npx lint-staged
   └── commit-msg       # 内容: npx commitlint --edit "$1"
├── package.json
└── .lintstagedrc.js

.husky/pre-commit 文件内容:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
 
npx lint-staged

调试技巧

# 启用详细日志
npx lint-staged --debug
 
# 查看匹配的文件(不执行命令)
npx lint-staged --diff
 
# 使用相对路径调试
npx lint-staged --relative

在 Monorepo 中的工程化

monorepo/
├── .husky/
│   └── pre-commit          # npx lint-staged
├── .lintstagedrc.js        # 根目录统一配置
├── packages/
│   ├── ui/
│   │   └── .eslintrc.js    # 各包独立配置
│   └── app/
│       └── .eslintrc.js
└── package.json

根目录 .lintstagedrc.js

export default {
  'packages/**/*.{js,ts,tsx}': (files) => {
    // 按包分组执行,避免重复初始化
    const packages = new Set(
      files.map(f => f.match(/^packages\/([^/]+)/)?.[1]).filter(Boolean)
    )
    const commands = []
    for (const pkg of packages) {
      commands.push(`pnpm --filter ./${pkg} exec eslint --fix`)
    }
    return commands
  },
}

性能与安全

性能考量

因素影响优化建议
暂存文件数量文件越多越慢lint-staged 只处理暂存文件,通常很快
命令初始化时间ESLint 配置复杂时初始化慢考虑使用 Oxlint/Biome 替代
Git stash 操作大仓库可能较慢升级到 Git ≥ 2.32.0
命令串行执行多个命令逐个执行使用 --concurrent 控制并发

性能优化建议:

# 使用 Biome 替代 ESLint + Prettier(15x 更快)
{
  '*.{js,ts,tsx}': 'biome check --apply'
}
 
# 使用 --quiet 减少输出
{
  '*.js': 'eslint --fix --quiet'
}

安全考量

方面说明
依赖安全lint-staged 本身无已知严重漏洞,Snyk 显示健康状态
命令注入风险glob 匹配的文件名直接作为命令参数,特殊文件名可能导致问题
Snap 沙箱兼容v17 修复了 Snap 安装 Node.js 的沙箱限制问题
Git 版本要求v17 起要求 Git ≥ 2.32.0,确保兼容性
敏感信息泄露建议配合 gitleaks 等工具扫描暂存文件中的密钥

依赖关系

lint-staged 的核心依赖:

lint-staged
├── picomatch          # Glob 匹配
├── execa              # 子进程执行
├── lilconfig          # 配置文件查找
├── chalk              # 终端彩色输出
├── commander          # CLI 参数解析
├── debug              # 调试日志
└── yaml               # YAML 配置解析

技术对比

lint-staged vs Lefthook

维度lint-stagedLefthook
语言Node.jsGo(单二进制文件)
职责仅处理暂存文件过滤与执行完整的 Git 钩子管理 + 文件过滤
是否需要配合 Husky✅ 是❌ 否(自身管理钩子)
启动速度需要 Node.js 运行时无运行时开销,毫秒级启动
并行执行❌ 顺序执行✅ 原生并行
配置格式JSON/JS/YAMLYAML
生态成熟度⭐⭐⭐⭐⭐ 行业标准⭐⭐⭐⭐ 快速增长
适合场景Node.js 项目、标准前端栈大型 Monorepo、追求极致性能

lint-staged vs pre-commit (Python)

维度lint-stagedpre-commit (Python)
语言Node.jsPython
平台Node.js 生态语言无关
文件过滤内置 glob 匹配内置 hooks 类型过滤
安装方式npm installpip install pre-commit
配置package.json / .lintstagedrc.pre-commit-config.yaml
适用项目前端/Node.js 项目多语言项目

lint-staged vs Husky(常见误解)

lint-staged 和 Husky 不是竞争关系,而是互补关系。

职责Huskylint-staged
管理 Git 钩子✅ 是❌ 否
过滤暂存文件❌ 否✅ 是
执行代码检查❌ 否(调用其他工具)✅ 是
工作层级Git 钩子层文件过滤与任务执行层

Husky 负责在 git commit 时触发钩子 → lint-staged 在钩子中执行,只检查暂存文件。

选型建议

小型项目 / 标准前端项目        → Husky + lint-staged(行业标准)
大型 Monorepo / 追求极致性能   → Lefthook(替代 Husky + lint-staged)
多语言项目                    → pre-commit (Python)
追求极致速度(Rust 工具链)    → Biome / Oxlint + 手动 Git hooks

最佳实践

1. 保持配置简洁

// ✅ 推荐:简洁清晰
export default {
  '*.{js,ts,tsx}': ['eslint --fix', 'prettier --write'],
  '*.{css,scss}': ['stylelint --fix', 'prettier --write'],
}
 
// ❌ 避免:过于复杂的逻辑
export default {
  '*': (files) => {
    // 数百行复杂逻辑...
  }
}

2. 使用 --fix 自动修复

export default {
  // ✅ 自动修复 + 格式化
  '*.{js,ts}': ['eslint --fix', 'prettier --write'],
 
  // ❌ 只检查不修复,发现问题后提交被拒,开发者还得手动修
  '*.{js,ts}': ['eslint'],
}

3. 命令顺序:先修复后格式化

export default {
  // ✅ 先 eslint 修复,再 prettier 格式化
  '*.js': ['eslint --fix', 'prettier --write'],
 
  // ❌ 顺序反了,eslint 修复可能会破坏 prettier 格式
  '*.js': ['prettier --write', 'eslint --fix'],
}

4. 搭配 commitlint 校验提交信息

.husky/commit-msg

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
 
npx commitlint --edit "$1"

5. 处理特殊文件路径

export default {
  // 使用函数式任务处理需要特殊逻辑的场景
  '*.js': (files) => {
    // 排除测试文件
    const sourceFiles = files.filter(f => !f.includes('.test.'))
    return [`eslint --fix ${sourceFiles.join(' ')}`]
  },
}

6. 使用 --max-warnings 控制质量

export default {
  // 有 warning 也不允许提交
  '*.js': 'eslint --fix --max-warnings=0',
}

7. CI 中也运行 lint-staged

# .github/workflows/ci.yml
- name: Run lint-staged
  run: npx lint-staged --diff=origin/${{ github.base_ref }}

8. 版本锁定

将 lint-staged 安装为 devDependency 而非全局工具,确保团队使用相同版本。

技术局限与边界

已知局限

局限说明应对策略
Node.js 运行时开销每次提交需启动 Node.js,Lefthook(Go)更快对速度敏感的项目考虑 Lefthook
无法并行执行命令多个命令按顺序执行使用 Biome 替代多个工具,减少命令数
大仓库性能Git 操作(stash、diff)在大仓库中较慢使用 shallow clone、稀疏 checkout
Monorepo 复杂性跨包依赖检查难以精确处理配合 Turborepo/Nx 的增量能力
无法检查类型错误TypeScript 类型检查通常需要项目上下文类型检查放 CI,lint-staged 只做语法检查
Git stash 恢复风险极端情况下(如进程被杀)stash 可能恢复失败lint-staged 有备份机制,但仍建议勤提交
Windows 兼容性部分场景下路径处理有问题使用正斜杠路径、测试 Windows 环境

何时不该用 lint-staged

  • 纯后端项目(无 Node.js 环境):考虑 pre-commit(Python)或 lefthook
  • 极小的脚本项目:增加工具链负担大于收益
  • 已有完善 CI 检查的单人项目:可选,但非必须
  • 非 Git 项目:lint-staged 依赖 Git 暂存区

学习资源

官方资源

优质教程

中文资源

对比与趋势

2026 年现状

版本动态

  • 最新版本 v17.0.8(2026年),要求 Node.js ≥ 22、Git ≥ 2.32.0
  • v17 引入了 npm staged publishing(分阶段发布)机制
  • 项目使用 Changesets 管理版本和发布流程
  • 持续活跃维护,CI 流水线已适配 Windows 2025/2026 运行环境

生态地位

lint-staged + Husky 在 2026 年仍然是前端项目的 行业标准配置,被绝大多数 Next.js、Vite、Create React App 等脚手架默认集成或推荐。

竞争趋势

  • Lefthook(Go 编写)作为一体化替代方案增长迅速,适合追求性能的大型项目
  • Biome(Rust 编写)作为 ESLint + Prettier 的替代,将 lint-staged 的任务执行时间缩短 15 倍
  • Oxlint(Rust 编写)提供极速 JavaScript 检查能力
  • hk(jdx)新工具,强调原生并行执行 linter

选型建议(2026)

标准前端项目(中小型)   → Husky + lint-staged(不变的首选)
大型 Monorepo           → Lefthook(替代 Husky + lint-staged)
追求极致开发体验         → Biome/Oxlint + lint-staged 或 Lefthook
全栈/多语言项目          → Lefthook 或 pre-commit (Python)

lint-staged 的核心价值 —— "只对暂存文件运行检查" —— 在 2026 年依然不可替代。即使底层工具(ESLint → Oxlint、Prettier → Biome)在更迭,lint-staged 作为暂存文件过滤层的定位依然稳固。