返回文章列表
技术实践

前端工程化(六):代码规范与提交门禁

ESLint、Prettier、TypeScript 和测试解决的是不同风险:Prettier 统一格式,ESLint 检查代码质量,TypeScript 检查静态类型关系,测试验证运行时行为。它们应该组成一条从本地到 CI 的质量门禁,而不是互相替代。

四个工具分别管什么

Prettier 的职责最集中:按照统一规则格式化代码。缩进、引号、换行和对象排列等问题交给它处理,可以减少团队成员之间的格式差异。它关注的是代码长什么样,不负责证明业务逻辑正确。

ESLint 的范围更广。它可以检查潜在错误、团队规范和部分最佳实践,例如未使用变量、危险写法、React 使用约束和依赖规则。ESLint 也可以配置格式规则,但在实际项目中通常让 Prettier 专注格式化,再通过 eslint-config-prettier 关闭 ESLint 中与 Prettier 冲突的规则,避免同一个格式问题被两个工具重复报告。

TypeScript 主要做静态类型检查和类型推导。它可以在开发和编译阶段发现参数类型不匹配、属性不存在和返回值不符合声明等问题,但类型信息通常会在编译成 JavaScript 时被擦除。接口真实返回值、用户输入、网络异常和业务行为仍然需要运行时校验与测试。

测试则通过真正执行代码验证运行时结果。单元测试可以验证函数分支,集成测试可以验证模块协作,端到端测试可以验证用户操作和页面流程。类型检查通过,并不代表接口数据一定符合预期,也不代表按钮点击后一定得到正确结果。

为什么要按顺序执行质量检查

一条常见的质量门禁顺序是:

plaintext
format -> lint -> typecheck -> test

第一步统一代码格式,尽早消除无意义的格式差异;第二步检查规范、潜在错误和最佳实践;第三步检查静态类型关系;最后执行成本更高、运行时间更长的测试。前面的检查通常更快,能够让明显问题尽早失败,减少在代码已经不符合规范时继续消耗测试资源。

本地开发可以使用自动格式化命令帮助修复代码。CI 通常使用 format:check 之类的检查模式,只判断代码是否符合格式要求,不直接修改构建环境中的文件。这样 CI 的结果能够准确反映提交内容本身。

本地 hook 和 CI 为什么都需要

pre-commit 适合在开发者提交前提供快速反馈,可以阻止明显不合格的代码进入版本历史。但本地 hook 可能没有安装,可能被跳过,也可能只在某一台机器的环境中通过。因此它更像第一道提醒和筛选。

CI 需要在干净环境中对分支或合并请求重新执行 lint、typecheck 和 test。CI 能统一 Node.js、包管理器、安装方式和命令,也能保证没有安装本地 hook 的开发者仍然受到同样的质量约束。最终是否允许合并,应由团队共同可见的 CI 结果决定。

本地通过而 CI 失败时,应对比 Node.js 和包管理器版本、lockfile 安装方式、环境变量、操作系统路径大小写、实际执行脚本和测试日志。网络、时间和并发顺序也可能让测试出现本地没有的失败。

从真实项目判断工程化现状

不能因为 package.json 没有某个脚本,就直接断定项目没有这项能力。脚本只是常用执行入口,依赖只能说明工具可能存在,不能证明工具已经接入并实际运行。还要检查工具配置、tsconfig.json、.husky、CI workflow、构建平台配置,并通过实际命令确认结果。

在 my-world 中,目前可以确认:

  • package.json 提供 lint: next lint,因此已有统一的 lint 入口。
  • package.json 提供多个测试脚本,但没有独立的 format 和 typecheck 脚本。
  • tsconfig.json 设置了 strict: true 和 noEmit: true,具备 TypeScript 静态检查基础。
  • 当前未发现仓库内的 .husky 或 .github/workflows 目录,因此不能确认本地提交 hook 和仓库级 CI 门禁已经接入。
  • lockfile 中存在 Prettier 依赖记录,但这只能证明依赖树中出现过它,不能证明项目已经配置格式化命令。

因此更准确的判断是:项目已经有 lint、测试和 TypeScript 配置基础,但代码质量门禁的自动化链路仍不完整。这个结论比笼统地说“整个项目工程化不完善”更有证据,也更适合面试表达。

一条最小可行的门禁方案

如果要补齐最小门禁,可以在 package.json 中明确四个入口:

JSON
{
  "scripts": {
    "format:check": "prettier --check .",
    "lint": "next lint",
    "typecheck": "tsc --noEmit",
    "test": "<项目测试命令>"
  }
}

其中 test 应替换为项目实际的测试命令或测试脚本集合。开发者本地可以执行格式化修复,再依次运行 lint、typecheck 和 test;CI 则通过 npm ci 安装依赖后执行同一套检查。若项目没有某个工具或脚本,应先补齐接入,再把它写进提交门禁,不能只依赖“依赖已经安装”这一事实。

有想法或建议? 联系我