ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Next.js 仓库代码规范体系:ESLint、Prettier 与 alex 的三层 Linting 实践

2026/9/7 18:34:28 拓冰建站 浏览量
Next.js 仓库代码规范体系:ESLint、Prettier 与 alex 的三层 Linting 实践 Next.js 仓库代码规范体系ESLint、Prettier 与 alex 的三层 Linting 实践【免费下载链接】next.jsThe React Framework项目地址: https://gitcode.com/GitHub_Trending/next/next.js本文围绕 Next.js 仓库的官方 Linting 指南展开系统讲解pnpm lint/pnpm lint-fix的完整执行链路从脚本编排、双配置 ESLint 架构IDE 快速模式与 CI 类型检查模式、Prettier 格式化规则到文档语言检查工具 alex 的配置细节并结合 ESLint 配置、Prettier 配置 等仓库源码文件帮助贡献者准确理解每一项规则的含义与作用范围从而在提交 PR 前高效通过代码规范检查。官方命令pnpm lint 与 pnpm lint-fixNext.js 仓库使用 ESLint。对全仓库执行 lint 检查pnpm lint如果出现错误可以运行 ESLint 和 Prettier 的自动修复pnpm lint-fix需要注意的是并非所有规则都能自动修复部分问题需要手动修改另外如果 alex 对文档提出语言警告需要按其提示修改相关措辞。pnpm lint 实际执行了哪些任务查看根目录 package.json 中的 scripts 定义可以还原pnpm lint的真实构成。它并不是单一的 ESLint 调用而是用npm-run-all并行跑六项检查lint: run-p test-types lint-typescript prettier-check \lint-eslint .\ lint-ast-grep lint-language check-unused-turbo-tasks, lint-fix: pnpm prettier-fix pnpm lint-eslint --fix ., lint-language: alex . --quiet, prettier-check: prettier --check ., prettier-fix: prettier --write ., lint-eslint: eslint --config eslint.cli.config.mjs, lint-ast-grep: ast-grep scan, lint-typescript: turbo run typescript,也就是说一次pnpm lint涵盖了子任务对应脚本作用test-typestsc根工程级 TypeScript 类型检查lint-typescriptturbo run typescript通过 Turbo 在各 workspace 包内做类型检查prettier-checkprettier --check .检查全仓库文件格式是否符合 Prettier 规则lint-eslint .eslint --config eslint.cli.config.mjs使用 CI 版配置含类型检查规则跑 ESLintlint-ast-grepast-grep scan用 ast-grep 规则集 做 AST 级模式检查lint-languagealex . --quiet用 alex 扫描文档与代码中的敏感措辞check-unused-turbo-tasksnode scripts/check-unused-turbo-tasks.mjs检查 Turbo 任务定义中是否有未使用的任务而pnpm lint-fix的构成更简单先prettier --write .重写格式再eslint --config eslint.cli.config.mjs --fix .自动修复可修复的 ESLint 问题。这也解释了文档中部分规则无法自动修复的原因——lint-fix只覆盖 Prettier 与 ESLint 两类可修复问题ast-grep 模式违规和 alex 的语言警告仍需手动处理。双配置 ESLintIDE 快速配置与 CLI 类型检查配置文档推荐在 VS Code 中安装 ESLint 插件以获得编辑器内实时提示并指出启用的规则见 ESLint 配置。实际上仓库维护了两套 ESLint 配置这一设计是理解 Next.js 规范体系的关键。eslint.config.mjs面向 IDE 的默认配置eslint.config.mjs 文件开头的注释明确说明了双配置策略// This is the default eslint config that is used by IDEs. It does not use // computation-heavy type-checked rules to ensure maximum responsiveness while // writing code. In addition, there is .eslintrc.cli.json that does use // type-checked rules in addition to the rules defined here, and it is used // when running pnpm lint-eslint locally or in CI.即IDE 中加载的是eslint.config.mjs不启用计算开销大的 type-checked 规则保证编辑响应速度而本地执行pnpm lint-eslint或 CI 时加载的是 eslint.cli.config.mjs它在基础配置之上追加类型检查规则。eslint.config.mjs的整体结构是一个 ESLint Flat Config 数组主要区块包括全局 ignore 规则从 .config/eslintignore.mjs 导入基于globalIgnores排除node_modules、.next、dist、crates/**、测试 fixture、编译产物packages/next/src/compiled/**等基础规则块作用于**/*.{js,jsx,mjs,ts,tsx,mts,mdx}用babel/eslint-parser解析presets: [next/babel]、supportsTopLevelAwait: true并打开reportUnusedDisableDirectives: error即无效的eslint-disable注释本身会报错Jest 测试块对test/**与**/*.test.ts(x)文件启用plugin:jest/recommended并针对 Next.js 自研测试运行器扩展了jest/no-standalone-expect将retry、itSkipDeploy、itCI、itHeaded、itTurbopack等自定义测试块函数识别为合法断言容器TypeScript 块对.ts/.tsx/.mts文件启用tseslint.configs.recommended与stylistic并按需关闭一批风格类规则如no-explicit-any、no-var-requires同时重写typescript-eslint/no-unused-vars允许_前缀的忽略变量packages 专属块对packages/**/*.ts(x)启用内部插件next/eslint-plugin-internal的typechecked-require、jsdoc/no-types、jsdoc/no-undefined-types等规则并对packages/**加强no-shadow与import/no-extraneous-dependencies禁止引入 package.json 未声明的运行时依赖。基础规则块中的一些代表性规则节选自 eslint.config.mjseqeqeq: [error, smart]、no-fallthrough: error、no-eval: error、no-unreachable: error等大量可靠性规则全部为errorreact-hooks/rules-of-hooks: error与react-hooks/exhaustive-deps: error对 React Hooks 使用强约束default-case要求 switch 有默认分支注释^no default$可豁免但这一规则在类型检查覆盖的文件中会被关闭见下文no-restricted-imports禁止直接导入*/next-devtools/dev-overlay*必须走next/dist/compiled/next-devtoolsno-restricted-syntax禁止substr()提示改用slice()/substring()并要求workUnitStore.type的判断必须使用穷举 switch 而非 if/三元——这些细节规则体现了用 lint 固化架构约束的思路。eslint.cli.config.mjsCI 的类型检查增强层eslint.cli.config.mjs 的内容非常精炼它继承基础配置后仅对**/*.ts与**/*.tsx开启parserOptions.project: true启用类型感知并追加规则rules: { typescript-eslint/switch-exhaustiveness-check: [ error, { requireDefaultForNonUnion: true }, ], }该文件注释说明类型检查规则非常慢且消耗大量内存因此排除了bench/**、examples/**、test/**、turbopack/**、evals/evals/**等非核心文件。为保持行为一致eslint.config.mjs中还有一个专门镜像这些files/ignoresglob 的配置块eslint.config.mjs在这些文件上关闭default-case——因为switch-exhaustiveness-check已强制 union/enum 的穷举覆盖再要求default反而是冗余的。注释特别提醒修改这两处 glob 时必须保持同步。Prettier 格式化配置Linting 文档推荐安装 VS Code 的 Prettier 插件格式配置位于 Prettier 配置。完整内容只有三行{ trailingComma: es5, singleQuote: true, semi: false }即ES5 兼容位置加尾逗号、统一单引号、不加分号。这解释了 Next.js 源码无分号 单引号的标志性风格。配套的文件排除清单在 .prettierignore其中有几个值得注意的排除项构建产物.next/、dist/、target/、compiled/pnpm-lock.yaml、test-timings.json等生成文件SWC/RSC 编译器测试输入文件如crates/next-custom-transforms/tests/fixture/...下的input.js——注释说明 prettier destroys use server/use client directives in multi-file code examples即格式化会破坏多文件示例中的指令 pragmapackages/next-codemod/**/*.js等转换测试 fixture。提交前格式化由 lint-staged 配置 自动完成husky 的pre-commit钩子.husky/pre-commit执行pnpm lint-staged规则为module.exports { *.{js,jsx,mjs,ts,tsx,mts,mdx}: [ prettier --with-node-modules --ignore-path .prettierignore --write, eslint --config eslint.config.mjs --fix, ], *.{json,md,css,html,yml,yaml,scss}: [ prettier --with-node-modules --ignore-path .prettierignore --write, ], *.rs: [rustfmt --edition 2024 --], }注意这里提交钩子使用的是 IDE 版eslint.config.mjs而非 CLI 版避免在提交时为全部 TS 文件跑重量级的类型检查另外的*.rs文件走rustfmt覆盖仓库中的 Rust 部分。husky 还有一个pre-push钩子用于拦截直接向canary保护分支推送的操作。alex面向包容性语言的文档检查Linting 文档还推荐在 VS Code 安装 AlexJS Linter 扩展配置位于 alex 配置。alex 用于扫描文档中可能对特定群体不友好的措辞是 Next.js 仓库少数作用于文字内容而非代码的 lint 工具对应pnpm lint-languagealex . --quiet。.alexrc 采用allow白名单机制放行了在 Next.js 语境下属于正常技术用法的词汇例如{ allow: [ attacks, color, dead, deno, dirty, execute, executed, execution, failed, failure, hook, hooks, invalid, simple, special, white, ... ] }可以看到白名单同时容纳了产品名deno、fly.io、railway、sst、技术语义词color、hooks、failed以及文档中确实需要的形容词simple、special、white。配套还有 .alexignore将CODE_OF_CONDUCT.md、examples/、各LICENSE.md、AGENTS.md等文件排除在扫描之外——这些文件要么本身就是第三方/模板内容要么不适合自动审查。贡献者如果在 PR 中收到 alex 警告按 Linting 文档的指引需要按其提示修改对应措辞而不是直接忽略。ast-grepAST 级模式检查的补充层虽然 Linting 文档主要介绍三个工具但从 package.json 的lint编排可以看到pnpm lint还包含ast-grep scan。ast-grep 基于 AST 模式匹配能表达 ESLint 规则难以覆盖的结构性约束其规则集位于 .config/ast-grep/rules/。以 no-typeof-window-require.yml 为例该规则禁止用typeof window条件门控require()调用severity: error language: TypeScript files: - packages/next/src/** rule: pattern: require($$$ARGS) inside: stopBy: end any: - kind: ternary_expression has: field: condition has: stopBy: end pattern: typeof window - kind: if_statement ...规则的 note 说明背后的架构原因用typeof window包裹require()会把服务端分支打进行者端 bundle正确做法是拆分为name.ts与name.browser.ts两个文件由scripts/generate-browser-variant-aliases.mjs自动完成浏览器变体别名。规则文件还注明 ast-grep 规则是单语言的.tsx版本由配套的no-typeof-window-require-tsx.yml覆盖两份 rule 体需保持同步。目录下的 rule-tests/ 与快照文件则为每条规则提供了可回归测试的 fixture保证规则本身的正确性。小结一次 pnpm lint 的完整检查矩阵综合以上仓库证据可以归纳出 Next.js 仓库pnpm lint的检查矩阵层工具作用对象配置位置可否自动修复格式Prettier全仓库文本文件.prettierrc.json、.prettierignore可pnpm prettier-fix代码规则IDEESLintJS/TS/MDXeslint.config.mjs、.config/eslintignore.mjs部分可代码规则CI类型感知ESLintTS/TSX 核心文件eslint.cli.config.mjs部分可AST 结构ast-greppackages/next/src/**等.config/ast-grep/rules/不可类型tsc / Turbo根工程与 workspacetsconfig.json等不可文档语言alex文档与代码文字.alexrc、.alexignore不可需按提示改措辞对贡献者而言日常开发流程是编辑器内由eslint.config.mjs Prettier 插件提供即时反馈提交时 husky 钩子对暂存文件跑lint-stagedPrettier 写入 ESLint--fix Rust 文件 rustfmt提交前最终用pnpm lint做全量验证遇到可修复错误时先跑pnpm lint-fix再手动处理剩余项。这套IDE 轻量、CI 重量、提交钩子兜底的分层设计在保证大型 monorepo 可维护性的同时把昂贵的类型检查规则限制在了必要的文件范围与执行时机内。【免费下载链接】next.jsThe React Framework项目地址: https://gitcode.com/GitHub_Trending/next/next.js创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考