Next.js 工程化配置:ESLint + Prettier + Husky 一站式搭建

周五晚上的噩梦
还记得上周五晚上,我刚准备关电脑回家,突然看到 Slack 上技术负责人发来一条消息:“你的 PR 里格式问题太多了,能先整理一下再提交吗?“我点开 GitHub,满屏的红色 diff,全是因为有的地方用了双引号,有的地方缩进不一致。
老实讲,那种感觉特别无力。我明明记得提交前运行过 npm run lint 的啊,为什么还是出问题?更尴尬的是,团队里另一个同事也遇到了类似情况,他的代码逻辑完全没问题,就是格式和我的不一样,结果合并时产生了一堆无意义的冲突。
你有没有遇到过这种情况?代码写得好好的,却因为格式问题在 PR review 上来回折腾,浪费大家时间。我当时就在想:有没有一劳永逸的解决方案,让机器自动帮我们搞定这些琐事?
答案是有的:ESLint + Prettier + Husky 这套组合拳。
为什么需要这三个工具?
说实话,刚听到这三个名字的时候,我也觉得有点复杂。但用了一段时间后,真的回不去了。让我分别说说它们的价值。
ESLint:代码质量的守护者
很多人以为 ESLint 只是用来检查代码格式的,其实它更重要的作用是捕获潜在的代码问题。
举个例子,Next.js 官方推荐使用 <Image> 组件而不是 HTML 的 <img> 标签,因为前者有自动优化功能。如果你不小心写了 <img>,ESLint 会立刻报错提醒你:
Error: Do not use <img>. Use Image from 'next/image' instead.这种提醒在开发阶段就能避免性能陷阱,比等到上线后发现图片加载慢再优化要高效得多。
Next.js 15 默认启用了 ESLint,但你需要正确配置才能发挥它的最大价值。
Prettier:格式化的终极方案
ESLint 专注于代码逻辑和质量,Prettier 则专注于代码格式。两者分工明确,不应该混淆。
我们团队之前经常为格式问题争论:有人喜欢单引号,有人喜欢双引号;有人习惯缩进 2 个空格,有人习惯 4 个空格。每次 code review 都要讨论这些无关紧要的细节,真的很浪费时间。
配置 Prettier 后,这些问题彻底消失了。你只需要在项目开始时和团队成员一起定好规则(比如统一用单引号、缩进 2 空格),之后 Prettier 会自动格式化所有代码。配置一次,终身受益。
Husky:自动化的关键
工具再好,如果要手动运行,总有人会忘记。
我自己就经历过好几次:本地开发时忘记运行 npm run lint,直接提交代码,结果 CI 流程失败,整个团队的部署都被阻塞了。那种尴尬感,真的不想再经历第二次。
Husky 的作用就是在你提交代码之前,自动运行检查。它会在 Git 的 pre-commit 阶段拦截你的提交,先运行 ESLint 和 Prettier,确保代码符合规范后才允许提交。
配合 lint-staged,Husky 只会检查你修改过的文件,而不是全项目扫描,所以速度非常快。你不用担心 pre-commit hook 拖慢开发节奏。
三者协同的威力
这三个工具组合起来的工作流程是这样的:
- ESLint 定义代码质量规则(比如不允许用
var,必须用const或let) - Prettier 统一代码格式(比如所有字符串都用单引号)
- Husky 在提交前自动运行检查,确保没有人遗漏
团队受益是显而易见的:
- PR review 时不再纠结格式问题,专注于业务逻辑
- 代码合并冲突减少(因为格式统一)
- CI 失败率降低(因为提交前已经检查过)
完整配置流程
好,下面进入实战环节。我会一步步带你配置这套工具链,尽量避免踩坑。
步骤 1:初始化 Next.js 项目
如果你已经有项目了,可以跳过这一步。如果是新项目,运行:
npx create-next-app@latest my-app
cd my-app创建项目时,记得选择 TypeScript 和 ESLint。Next.js 15 默认会帮你启用 ESLint,这省了不少事。
步骤 2:安装依赖
运行下面的命令(我用的是 pnpm,你也可以用 npm 或 yarn):
pnpm add -D eslint eslint-config-next prettier eslint-config-prettier husky lint-staged这里简单解释一下每个包的作用:
eslint:ESLint 核心eslint-config-next:Next.js 官方的 ESLint 配置(包含 Next.js 特有的规则)prettier:Prettier 核心eslint-config-prettier:关闭 ESLint 中与 Prettier 冲突的格式规则husky:Git hooks 管理工具lint-staged:只对暂存的文件运行检查
注意:不要安装 eslint-plugin-prettier。很多教程会推荐这个包,但它会让 Prettier 作为 ESLint 规则运行,导致性能问题。正确的做法是让 ESLint 和 Prettier 分开运行。
步骤 3:配置 ESLint
这一步是最容易踩坑的,尤其是 Next.js 15 升级到 ESLint 9 后,配置格式发生了变化。
使用 ESLint 9 的 Flat Config 格式(推荐)
在项目根目录创建 eslint.config.mjs:
// eslint.config.mjs
import { FlatCompat } from '@eslint/eslintrc';
import nextPlugin from '@next/eslint-plugin-next';
const compat = new FlatCompat();
export default [
...compat.extends('next/core-web-vitals'),
{
plugins: {
'@next/next': nextPlugin,
},
rules: {
'@next/next/no-img-element': 'error',
'react/no-unescaped-entities': 'off',
// 这里可以添加你自己的规则
},
},
{
ignores: ['.next/', 'node_modules/', 'out/'],
},
];关键点:
- ESLint 9 不再使用
.eslintrc.json,而是用 flat config 格式(eslint.config.mjs) - 如果你升级到 Next.js 15 后遇到 “The Next.js plugin was not detected” 错误,大概率是配置格式不对
- Next.js 16 将移除
next lint命令,所以提前适应新格式是明智的
降级方案(如果遇到兼容性问题)
如果你暂时不想折腾 flat config,可以设置环境变量降级到 ESLint 8 的配置格式:
ESLINT_USE_FLAT_CONFIG=false然后继续使用 .eslintrc.json:
{
"extends": ["next/core-web-vitals", "prettier"],
"rules": {
"@next/next/no-img-element": "error"
}
}不过我建议还是尽早迁移到 flat config,毕竟这是未来的趋势。
步骤 4:配置 Prettier
在项目根目录创建 .prettierrc.json:
{
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"tabWidth": 2,
"printWidth": 80,
"arrowParens": "avoid"
}这些配置是我个人比较喜欢的,你可以根据团队习惯调整:
singleQuote: true:我更喜欢单引号,看起来简洁printWidth: 80:每行最多 80 个字符,适合并排显示多个编辑器窗口trailingComma: 'es5':在对象和数组的最后一项加逗号,这样 Git diff 会更干净
再创建 .prettierignore,告诉 Prettier 忽略哪些文件:
.next
out
node_modules
public
*.lockVSCode 集成(可选但推荐)
如果你用 VSCode,可以创建 .vscode/settings.json,实现保存时自动格式化:
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}这样每次按 Ctrl + S 保存文件时,Prettier 会自动格式化代码。真的很爽。
步骤 5:配置 Husky + lint-staged
这一步是整个配置流程的精华,也是最能提升团队协作效率的部分。
初始化 Husky
运行:
pnpm dlx husky init这个命令会自动创建 .husky/ 文件夹,并在 package.json 中添加 prepare 脚本:
{
"scripts": {
"prepare": "husky install"
}
}prepare 脚本的作用是确保团队成员在运行 pnpm install 时,自动安装 Husky hooks。这样新加入的同事不需要额外操作,克隆项目后直接就能享受到自动化检查的保护。
配置 pre-commit hook
编辑 .husky/pre-commit 文件:
pnpm lint-staged就这么简单。每次你运行 git commit 时,Husky 会先执行 pnpm lint-staged。
配置 lint-staged
在项目根目录创建 .lintstagedrc.mjs:
export default {
'*.{js,jsx,ts,tsx}': [
'eslint --fix',
'prettier --write',
],
'*.{json,md,css}': [
'prettier --write',
],
};这段配置的意思是:
- 对于
.js、.jsx、.ts、.tsx文件,先运行eslint --fix(自动修复问题),再运行prettier --write(格式化) - 对于
.json、.md、.css文件,只运行prettier --write
性能优化技巧:
- 只检查暂存文件:lint-staged 会自动过滤出
git add的文件,不会扫描整个项目 - 避免全局检查:千万不要在 pre-commit 中运行
pnpm lint(这会检查全项目,速度很慢) - 跳过测试:pre-commit 只做格式检查和基础的代码质量检查,复杂的测试留给 CI
- 紧急提交时跳过:如果你确实需要跳过检查(比如紧急修复线上问题),可以用
git commit --no-verify
常见问题排查
Windows 环境下 Husky 不生效
如果你用 Windows,确保你的 Git 配置使用的是 Git Bash,而不是 CMD 或 PowerShell。另外检查 .husky/pre-commit 文件是否有执行权限:
chmod +x .husky/pre-commithook 执行太慢
如果 pre-commit hook 运行超过 10 秒,检查你的 lint-staged 配置,确保没有误配置全项目检查。正常情况下,只检查几个文件的 lint-staged 应该在 2-3 秒内完成。
验证配置
配置完成后,我们来验证一下是否生效。
测试步骤
- 随便修改一个文件,故意加入格式问题(比如把单引号改成双引号,或者删掉几个分号)
- 运行
git add . - 运行
git commit -m "test" - 观察终端输出
成功标志
如果配置正确,你会看到类似这样的输出:
✔ Preparing lint-staged...
✔ Running tasks for staged files...
✔ Applying modifications from tasks...
✔ Cleaning up temporary files...然后打开你修改的文件,会发现格式问题已经被自动修复了。这就是自动化的魅力。
如果失败了
- 检查
.husky/pre-commit文件是否存在,内容是否正确 - 检查
.lintstagedrc.mjs文件是否在项目根目录 - 尝试手动运行
pnpm lint-staged,看是否有报错信息
进阶配置
基础配置已经能满足大部分需求了,但如果你想要更严格的代码质量管理,可以考虑以下进阶配置。
添加 commitlint(规范提交信息)
除了代码格式,提交信息(commit message)的规范也很重要。commitlint 可以确保团队成员都遵循统一的提交信息格式(比如 Conventional Commits)。
安装依赖:
pnpm add -D @commitlint/cli @commitlint/config-conventional创建 commitlint.config.mjs:
export default {
extends: ['@commitlint/config-conventional'],
};添加 commit-msg hook:
echo "pnpm commitlint --edit \$1" > .husky/commit-msg现在,如果你的提交信息不符合规范(比如 git commit -m "fix bug" 而不是 git commit -m "fix: bug"),提交会被拦截。
添加 TypeScript 类型检查
如果你希望提交前自动运行 TypeScript 类型检查,可以修改 .lintstagedrc.mjs:
export default {
'*.{ts,tsx}': [
() => 'tsc --noEmit', // 类型检查
'eslint --fix',
'prettier --write',
],
'*.{js,jsx}': [
'eslint --fix',
'prettier --write',
],
'*.{json,md,css}': [
'prettier --write',
],
};注意:tsc --noEmit 会检查整个项目的类型,速度比较慢。如果你的项目很大,可能会拖慢 pre-commit hook。我个人建议把类型检查留给 CI,pre-commit 只做格式和基础检查。
Monorepo 配置
如果你的项目是 Monorepo(比如用 pnpm workspace 或 Turborepo),配置稍微复杂一些:
- 在根目录安装 Husky 和 lint-staged
- 在每个 package 下创建独立的
.lintstagedrc.mjs - 避免配置”泄漏”到其他 package
具体配置可以参考 lint-staged 的官方文档。
常见问题与解决方案
配置过程中,你可能会遇到一些问题。这里总结几个常见的坑和解决方案。
Q1: ESLint 和 Prettier 规则冲突怎么办?
症状:ESLint 报错说某行代码格式不对,但 Prettier 格式化后又回到原样。
解决方案:
确保你安装了 eslint-config-prettier,并且在 ESLint 配置中最后 extends prettier:
export default [
...compat.extends('next/core-web-vitals'),
...compat.extends('prettier'), // 放在最后
];eslint-config-prettier 会关闭 ESLint 中所有与 Prettier 冲突的格式规则,让 Prettier 专注于格式化,ESLint 专注于代码质量。
Q2: Next.js 15 升级后 ESLint 报错 “plugin not detected”
症状:运行 pnpm lint 时报错:
Error: The Next.js plugin was not detected in your ESLint configuration.解决方案:
这通常是因为 ESLint 9 的 flat config 格式不对。检查你的 eslint.config.mjs 是否正确导入了 @next/eslint-plugin-next:
import nextPlugin from '@next/eslint-plugin-next';
export default [
{
plugins: {
'@next/next': nextPlugin,
},
},
];如果实在搞不定,可以暂时设置 ESLINT_USE_FLAT_CONFIG=false 降级到旧格式。
Q3: pre-commit hook 太慢怎么优化?
症状:每次提交都要等 10 秒以上,严重影响开发效率。
解决方案:
- 确认 lint-staged 只检查暂存文件(正常情况下应该是自动的)
- 移除 pre-commit 中的测试脚本(测试应该在 CI 阶段运行)
- 如果项目很大,考虑只对
.ts和.tsx文件运行 ESLint,其他文件只运行 Prettier
Q4: 团队成员没有安装 Husky hooks
症状:新同事克隆项目后,提交代码时没有触发 pre-commit hook。
解决方案:
确保 package.json 中有 prepare 脚本:
{
"scripts": {
"prepare": "husky install"
}
}告诉同事运行一次 pnpm install,Husky hooks 会自动安装。
Q5: Windows 环境下 Husky 不生效
症状:Windows 用户提交代码时,pre-commit hook 没有运行。
解决方案:
- 确保 Git 配置使用的是 Git Bash(而不是 CMD)
- 检查
.husky/pre-commit文件权限,尝试手动添加执行权限:
chmod +x .husky/pre-commit- 如果还是不行,尝试重新初始化 Husky:
rm -rf .husky
pnpm dlx husky init总结与最佳实践
配置这套工具链花了我大概半小时,但它给团队带来的价值是长期的。
核心收益
- 代码质量提升:ESLint 在开发阶段就能捕获潜在问题,避免线上事故
- 团队协作高效:统一的代码格式,减少无意义的 PR 争论和合并冲突
- 自动化保障:Husky 确保每次提交都符合规范,再也不用担心忘记检查
最佳实践建议
- 渐进式配置:不要一开始就配置很严格的规则。先用默认配置跑一段时间,发现问题再逐步调整。
- 团队共识:Prettier 配置(比如单引号 vs 双引号)需要团队成员一起讨论决定,不要自己一个人定。
- 性能优先:pre-commit hook 只做必要的检查,复杂的测试留给 CI。
- 定期更新:关注 Next.js 和 ESLint 的版本变化,尤其是 Next.js 16 即将移除
next lint命令。
下一步行动
如果你还没有在项目中配置这套工具链,我建议你现在就试试看。跟着这篇文章一步步操作,半小时就能搞定。
然后把配置分享给团队成员,统一大家的开发环境。
最后,根据团队的具体情况,调整 Prettier 和 ESLint 规则。记住,工具是为人服务的,不要被工具绑架。
个人经验
说实话,配置这套工具链刚开始确实会觉得麻烦,尤其是遇到 ESLint 9 的 flat config 迁移问题时,我也折腾了好一阵子。但用上之后真的回不去了。
现在我每次提交代码,完全不用担心格式问题,也不用担心忘记运行 lint。pre-commit hook 会自动帮我检查一切,那种安心感真的很棒。
团队的 PR review 效率也明显提升了。以前大家会在 PR 里讨论”这里应该用单引号还是双引号”,现在完全不会出现这种情况,因为 Prettier 早就统一好了。我们可以把时间花在讨论业务逻辑和架构设计上,而不是纠结格式细节。
这种自动化带来的效率提升,真的值得花这点时间配置。
希望这篇文章能帮到你。如果在配置过程中遇到问题,欢迎在评论区留言,我会尽力帮你解答。
祝你配置顺利!
12 分钟阅读 · 发布于: 2026年1月6日 · 修改于: 2026年1月22日
相关文章
Next.js 电商实战:购物车与 Stripe 支付完整实现指南

Next.js 电商实战:购物车与 Stripe 支付完整实现指南
Next.js 文件上传完整指南:S3/七牛云预签名URL直传实战

Next.js 文件上传完整指南:S3/七牛云预签名URL直传实战
Next.js 单元测试实战:Jest + React Testing Library 完整配置指南


评论
使用 GitHub 账号登录后即可评论