Files
lingxi/docs/工程规范/03-格式化与Lint.md
T
Stev_Wang 00ae12435e docs(specs): add AGENTS.md and engineering guidelines
项目尚无统一工程规范,AI 助手与研发各自发挥导致返工风险。建立
总纲 + 细则两层结构:AGENTS.md 只写硬约束与索引(14 条红线、技术栈
基线、仓库结构、命令契约),细则拆为 10 份文档覆盖 Git、代码风格、
格式化、API 与路由、数据库、测试与 CI、Review、日志、密钥、资产命名。

影响面:仅文档。约束力从本轮起对新建代码生效;与现状冲突处以文档为准。
回滚方式:git revert 本提交。
2026-11-02 15:09:51 +08:00

5.8 KiB
Raw Blame History

03 · 格式化与 Lint

项 内容
文档版本 V1.0(2026-11-02)
依据 技术架构 §2.2(前端)、§10.1(工程约定)、§4.6(CI/CD)
适用范围 全仓库可执行文件
强制级别 强制(CI 门禁,不允许「先合并后修」)

1 一句话原则

格式交给工具,评审只看逻辑。 任何格式争论都应由配置解决,禁止在 Review 中讨论空格与换行。


2 Prettier(唯一格式化器)

配置项 值 说明
printWidth 100 与技术架构示例行宽一致
tabWidth 2
useTabs false
semi true
singleQuote true
trailingComma all
arrowParens always
endOfLine lf 跨平台一致
plugins prettier-plugin-tailwindcss(仅 apps/web) 若引入 Tailwind;未引入则不加

规则:

  • FMT-01 只允许一个 Prettier 版本、一个根配置;子包不得覆盖。
  • FMT-02 禁止在文件中写 prettier-ignore,除非是生成代码或大段 markdown 表格,并注明原因。
  • FMT-03 CI 执行 pnpm format:check,失败即阻断。
  • FMT-04 禁止把格式化产生的无关改动混进功能 PR(会产生冲突与 Review 噪音)。

3 ESLint(ESLint 9 flat config)

项 约定
配置位置 根 eslint.config.mjs,按 apps/*、packages/* 分层 export
基础 @eslint/js recommended + typescript-eslint 的 strictTypeChecked + stylisticTypeChecked
前端附加 eslint-plugin-react-hooks、eslint-plugin-react-refresh、jsx-a11y
导入排序 eslint-plugin-simple-import-sort
命名检查 @typescript-eslint/naming-convention(对应 02 §1)

3.1 必须为 error 的规则

规则 目的
@typescript-eslint/no-explicit-any 禁 any
@typescript-eslint/no-floating-promises 禁未处理 Promise
@typescript-eslint/no-misused-promises 禁 async 传入非异步回调位
@typescript-eslint/consistent-type-imports 类型导入用 import type
@typescript-eslint/no-unnecessary-condition 消除冗余判断(strict 下有效)
no-restricted-imports UI / 图标白名单(见 §3.2)
no-console 业务代码禁用,scripts/** 与 worker 的 logger 除外
import/no-cycle 禁循环依赖
react-hooks/rules-of-hooks / exhaustive-deps Hooks 正确性
jsx-a11y/* 关键项 可访问性底线

3.2 白名单(no-restricted-imports 强制)

禁止导入(含子路径):

@douyinfe/semi-ui          ← 只能用 @douyinfe/semi-ui-19
antd  @ant-design/*  @arco-design/*
@douyinfe/semi-icons  @ant-design/icons  react-icons  lucide-react  @heroicons/*
element-plus  naive-ui  @mui/*  @chakra-ui/*

规则:

  • FMT-05 图标只能 import { IconXxx } from '@lingxi/ui/icons';禁止 import * as Icons、禁止直接引 remixicon/icons/...。
  • FMT-06 SVG 内联仅允许品牌 Logo(packages/ui/brand/),其他一律走图标出口。
  • FMT-07 颜色字面量(#rrggbb、rgb()在 apps/web 内禁用,除非在 packages/ui/theme/ 的 token 定义文件。

3.3 允许 warn 的规则

@typescript-eslint/no-non-null-assertion(须注释证明非空)、complexity(> 15 警告)、max-lines-per-function(> 50 警告)。


4 提交钩子(本地)

钩子 工具 行为
pre-commit husky + lint-staged 仅对暂存文件跑 eslint --fix + prettier --write
commit-msg commitlint 校验 Conventional Commits(见 01 §2)
pre-push husky 跑 pnpm typecheck(本地拦截类型错误,避免浪费 CI)
  • FMT-08 lint-staged 只处理暂存文件,禁止在钩子里跑全量 lint / 全量测试(太慢会诱发 --no-verify)。
  • FMT-09 禁止 git commit --no-verify;如确因钩子故障,须在 PR 描述说明并附 CI 结果。

5 CI 门禁(阻断项)

阶段 命令 失败后果
安装 pnpm install --frozen-lockfile 阻断(lock 不一致直接失败)
格式 pnpm format:check 阻断
Lint pnpm lint --max-warnings=0 阻断
类型 pnpm typecheck 阻断
单测 pnpm test -- --coverage 阻断(覆盖率不得低于基线)
迁移 prisma migrate diff 校验 schema 与迁移一致 阻断
构建 pnpm build 阻断
安全 依赖审计 + 镜像高危漏洞 阻断(高危 0)
  • FMT-10 CI 与本地必须使用同一份配置,禁止 CI 单独放宽规则。
  • FMT-11 覆盖率基线只升不降;下调须在 PR 说明理由并由技术负责人批准。

6 例外与豁免

场景 做法
生成代码(Prisma Client、OpenAPI 类型) 在 eslint.config.mjs 中按路径 ignores,禁止在生成文件内加注释
第三方类型缺陷 文件级 /* eslint-disable rule -- 原因 */,必须写原因并在 PR 说明
单行特殊语法 行内 // eslint-disable-next-line rule -- 原因
全文件 disable 禁止;确需则改为局部 disable 或调整规则配置
  • FMT-12 任何 eslint-disable 都必须写明原因与到期处理方式(升级依赖 / 提 issue)。
  • FMT-13 规则调整(新增 / 降级 / 关闭)必须单独 PR,说明影响文件数与整改计划。

7 检查清单

  • pnpm format:check 通过,无格式化噪音混入
  • pnpm lint --max-warnings=0 通过
  • pnpm typecheck 通过
  • 无新增 eslint-disable;已有的都有原因
  • 未引入禁用包 / 禁用图标库
  • 无散落色值,样式走 token