chore: 合并 dev-code-format-frontend 到 master
This commit is contained in:
140
openspec/specs/frontend-lint-rules/spec.md
Normal file
140
openspec/specs/frontend-lint-rules/spec.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# 前端 Lint 规则
|
||||
|
||||
## Purpose
|
||||
|
||||
TBD - 定义前端 ESLint 规则配置、构建集成 lint 检查、以及自定义规则
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: ESLint 规则配置
|
||||
|
||||
前端 SHALL 在 `eslint.config.js` 中配置以下规则:
|
||||
|
||||
- `@tanstack/query/exhaustive-deps`: `error` — queryFn 中使用的变量 SHALL 出现在 queryKey 中
|
||||
- `@tanstack/query/no-void-query-fn`: `error` — queryFn SHALL 有返回值
|
||||
- `@tanstack/query/stable-query-client`: `error` — QueryClient SHALL NOT 在组件渲染中创建
|
||||
- `@tanstack/query/no-unstable-deps`: `error` — query 选项中 SHALL NOT 有不稳定引用
|
||||
- `@tanstack/query/infinite-query-property-order`: `error` — infinite query 属性顺序 SHALL 规范
|
||||
- `@tanstack/query/mutation-property-order`: `error` — mutation 回调顺序 SHALL 规范
|
||||
- `@tanstack/query/no-rest-destructuring`: `warn` — query 结果 SHALL NOT 使用 rest 解构
|
||||
- `no-console`: `['error', { allow: ['warn', 'error'] }]` — 代码中 SHALL NOT 使用 `console.log`、`console.info`、`console.debug` 等,仅允许 `console.warn` 和 `console.error`
|
||||
- `@typescript-eslint/consistent-type-imports`: `['error', { prefer: 'type-imports', fixStyle: 'inline-type-imports' }]` — type import SHALL 使用内联风格 `import { type Foo }`
|
||||
- `@typescript-eslint/no-non-null-assertion`: `error` — 代码中 SHALL NOT 使用 `foo!` 非空断言
|
||||
|
||||
#### Scenario: TanStack Query 规则未启用时构建失败
|
||||
|
||||
- **WHEN** `eslint.config.js` 中未配置 TanStack Query 的 `flat/recommended` 规则
|
||||
- **THEN** 前端构建 SHALL 失败
|
||||
|
||||
#### Scenario: 使用 console.log 时构建失败
|
||||
|
||||
- **WHEN** 源代码中出现 `console.log(...)` 调用
|
||||
- **THEN** ESLint SHALL 报告错误
|
||||
- **THEN** 前端构建 SHALL 失败
|
||||
|
||||
#### Scenario: 使用 console.warn 时不报错
|
||||
|
||||
- **WHEN** 源代码中出现 `console.warn(...)` 调用
|
||||
- **THEN** ESLint SHALL NOT 报告错误
|
||||
|
||||
#### Scenario: 使用独立 type import 时自动修复
|
||||
|
||||
- **WHEN** 源代码中出现 `import type { Foo } from 'module'`
|
||||
- **THEN** `eslint --fix` SHALL 自动修复为 `import { type Foo } from 'module'`
|
||||
|
||||
#### Scenario: 使用非空断言时构建失败
|
||||
|
||||
- **WHEN** 源代码中出现 `foo!.bar` 非空断言
|
||||
- **THEN** ESLint SHALL 报告错误
|
||||
|
||||
### Requirement: 构建集成 lint 检查
|
||||
|
||||
前端 SHALL 在 `build` 命令中集成 ESLint 检查和 Prettier 格式检查。
|
||||
|
||||
#### Scenario: 构建时执行 lint 和格式检查
|
||||
|
||||
- **WHEN** 执行 `bun run build`
|
||||
- **THEN** 构建 SHALL 依次执行 `tsc -b`、`bun run check`、`vite build`
|
||||
- **THEN** `bun run check` SHALL 执行 `bun run lint && bun run format:check`
|
||||
- **THEN** 若 `eslint .` 报告任何错误,构建 SHALL 中断
|
||||
- **THEN** 若 `prettier --check .` 报告任何格式问题,构建 SHALL 中断
|
||||
|
||||
#### Scenario: lint 警告不中断构建
|
||||
|
||||
- **WHEN** `eslint .` 仅报告警告(无错误)
|
||||
- **THEN** 构建 SHALL 继续执行格式检查和 `vite build`
|
||||
|
||||
#### Scenario: 单独执行 lint
|
||||
|
||||
- **WHEN** 执行 `bun run lint`
|
||||
- **THEN** SHALL 运行 `eslint .`
|
||||
|
||||
#### Scenario: 自动修复 lint 问题
|
||||
|
||||
- **WHEN** 执行 `bun run lint:fix`
|
||||
- **THEN** SHALL 运行 `eslint . --fix`
|
||||
|
||||
#### Scenario: 统一检查命令
|
||||
|
||||
- **WHEN** 执行 `bun run check`
|
||||
- **THEN** SHALL 运行 `bun run lint && bun run format:check`
|
||||
- **THEN** lint 错误和格式问题 SHALL 都被检查
|
||||
|
||||
#### Scenario: 统一修复命令
|
||||
|
||||
- **WHEN** 执行 `bun run fix`
|
||||
- **THEN** SHALL 运行 `bun run lint:fix && bun run format`
|
||||
- **THEN** lint 问题 SHALL 被修复
|
||||
- **THEN** 文件 SHALL 被格式化
|
||||
|
||||
### Requirement: 自定义规则禁止硬编码颜色
|
||||
|
||||
前端 SHALL 提供自定义 ESLint 规则 `no-hardcoded-color-in-style`,检测 JSX style 属性中的硬编码颜色值。
|
||||
|
||||
#### Scenario: 检测十六进制颜色
|
||||
|
||||
- **WHEN** JSX style 属性值匹配 `#xxx` 或 `#xxxxxx` 格式
|
||||
- **THEN** 规则 SHALL 报告警告
|
||||
- **THEN** 警告消息 SHALL 提示使用 `var(--td-*)` CSS Token
|
||||
|
||||
#### Scenario: 检测 rgb/rgba/hsl 颜色函数
|
||||
|
||||
- **WHEN** JSX style 属性值匹配 `rgb()`、`rgba()`、`hsl()` 格式
|
||||
- **THEN** 规则 SHALL 报告警告
|
||||
|
||||
#### Scenario: 允许 CSS Token 引用
|
||||
|
||||
- **WHEN** JSX style 属性值为 `var(--td-*)` 格式
|
||||
- **THEN** 规则 SHALL NOT 报告
|
||||
|
||||
#### Scenario: 允许特殊颜色关键字
|
||||
|
||||
- **WHEN** JSX style 属性值为 `inherit`、`transparent`、`currentColor`、`none`、`unset`、`initial`
|
||||
- **THEN** 规则 SHALL NOT 报告
|
||||
|
||||
#### Scenario: 允许数字值
|
||||
|
||||
- **WHEN** JSX style 属性值为数字(如 `0`、`16`)
|
||||
- **THEN** 规则 SHALL NOT 报告
|
||||
|
||||
### Requirement: 自定义规则存放位置
|
||||
|
||||
自定义 ESLint 规则 SHALL 存放在 `frontend/eslint-rules/` 目录中。
|
||||
|
||||
#### Scenario: 自定义规则目录结构
|
||||
|
||||
- **WHEN** 添加自定义 ESLint 规则
|
||||
- **THEN** 规则文件 SHALL 放置在 `frontend/eslint-rules/` 目录下
|
||||
- **THEN** `eslint.config.js` SHALL 通过相对路径引用本地插件
|
||||
- **THEN** 自定义规则 SHALL NOT 作为 npm 包发布
|
||||
|
||||
### Requirement: ESLint 与 Prettier 集成配置
|
||||
|
||||
前端 SHALL 在 `eslint.config.js` 中集成 `eslint-config-prettier`,确保 ESLint 和 Prettier 职责分离且不冲突。
|
||||
|
||||
#### Scenario: 职责分离
|
||||
|
||||
- **WHEN** 检查代码
|
||||
- **THEN** ESLint SHALL 负责代码质量检查(如未使用变量、语法错误)
|
||||
- **THEN** Prettier SHALL 负责代码格式化(如缩进、引号、分号)
|
||||
- **THEN** 两者 SHALL NOT 重复检查同一规则
|
||||
@@ -482,6 +482,9 @@ TBD - 提供供应商、模型配置和用量统计的前端管理界面
|
||||
- **THEN** TypeScript 配置 SHALL 开启 noUncheckedIndexedAccess
|
||||
- **THEN** 所有代码 SHALL NOT 使用 any 类型
|
||||
- **THEN** tsconfig SHALL 合并为单文件(不使用 project references)
|
||||
- **THEN** type import SHALL 使用内联风格 `import { type Foo }`
|
||||
- **THEN** 代码 SHALL NOT 使用非空断言 `foo!`
|
||||
- **THEN** 代码 SHALL NOT 使用 `console.log`、`console.info`、`console.debug`(仅允许 `console.warn` 和 `console.error`)
|
||||
|
||||
#### Scenario: React 函数组件
|
||||
|
||||
@@ -505,6 +508,30 @@ TBD - 提供供应商、模型配置和用量统计的前端管理界面
|
||||
- **THEN** Vite SHALL 对业务代码执行混淆处理
|
||||
- **THEN** 混淆 SHALL 仅应用于 src 目录下的业务代码
|
||||
- **THEN** 混淆 SHALL NOT 应用于 node_modules 中的第三方库
|
||||
- **THEN** 构建流程 SHALL 在 vite build 之前执行 ESLint 检查和 Prettier 格式检查
|
||||
- **THEN** ESLint 检查失败 SHALL 中断构建
|
||||
- **THEN** Prettier 格式检查失败 SHALL 中断构建
|
||||
|
||||
### Requirement: 开发环境格式化工具
|
||||
|
||||
前端 SHALL 配置开发环境格式化工具,确保开发者保存时自动格式化代码。
|
||||
|
||||
#### Scenario: VS Code 保存时自动格式化
|
||||
|
||||
- **WHEN** 开发者在 VS Code 中保存文件
|
||||
- **THEN** 文件 SHALL 自动使用 Prettier 格式化
|
||||
- **THEN** ESLint 可修复的问题 SHALL 自动修复
|
||||
|
||||
#### Scenario: 编辑器统一配置
|
||||
|
||||
- **WHEN** 开发者在编辑器中打开项目
|
||||
- **THEN** 编辑器 SHALL 自动应用 `.editorconfig` 配置
|
||||
- **THEN** 编辑器 SHALL 使用 2 空格缩进、UTF-8 编码、Unix 换行符
|
||||
|
||||
#### Scenario: VS Code 推荐安装扩展
|
||||
|
||||
- **WHEN** 开发者使用 VS Code 打开项目
|
||||
- **THEN** VS Code SHALL 提示安装 Prettier 和 ESLint 扩展
|
||||
|
||||
### Requirement: 与后端 API 通信
|
||||
|
||||
|
||||
232
openspec/specs/prettier-formatting/spec.md
Normal file
232
openspec/specs/prettier-formatting/spec.md
Normal file
@@ -0,0 +1,232 @@
|
||||
# Prettier 代码格式化
|
||||
|
||||
## Purpose
|
||||
|
||||
定义前端代码格式化规则、工具集成、编辑器配置,确保多人协作时代码风格一致。
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement: Prettier 核心配置
|
||||
|
||||
前端 SHALL 在 `.prettierrc` 文件中配置以下格式化规则:
|
||||
|
||||
- `semi`: `false` — 语句末尾 SHALL NOT 使用分号
|
||||
- `singleQuote`: `true` — 字符串 SHALL 使用单引号
|
||||
- `jsxSingleQuote`: `true` — JSX 属性 SHALL 使用单引号
|
||||
- `tabWidth`: `2` — 缩进 SHALL 使用 2 个空格
|
||||
- `useTabs`: `false` — 缩进 SHALL NOT 使用制表符
|
||||
- `trailingComma`: `"es5"` — 多行结构末尾 SHALL 使用 ES5 兼容的尾随逗号
|
||||
- `printWidth`: `120` — 每行最大字符数 SHALL 为 120
|
||||
- `bracketSpacing`: `true` — 对象字面量花括号内 SHALL 有空格
|
||||
- `arrowParens`: `"always"` — 箭头函数参数 SHALL 始终使用括号
|
||||
- `endOfLine`: `"lf"` — 换行符 SHALL 使用 Unix 风格 (LF)
|
||||
- `proseWrap`: `"preserve"` — Markdown 文本换行 SHALL 保持原样
|
||||
- `htmlWhitespaceSensitivity`: `"css"` — HTML 空白处理 SHALL 根据 CSS display 属性
|
||||
- `embeddedLanguageFormatting`: `"auto"` — 嵌入语言(如 Markdown 中的代码块)SHALL 自动格式化
|
||||
- `singleAttributePerLine`: `false` — JSX 多属性 SHALL NOT 强制每行一个
|
||||
|
||||
#### Scenario: 格式化 JavaScript 代码
|
||||
|
||||
- **WHEN** 运行 `prettier --write` 格式化 JavaScript 文件
|
||||
- **THEN** 代码 SHALL 使用单引号、无分号、2 空格缩进
|
||||
- **THEN** 行宽超过 120 字符时 SHALL 自动换行
|
||||
|
||||
#### Scenario: 格式化 TypeScript 代码
|
||||
|
||||
- **WHEN** 运行 `prettier --write` 格式化 TypeScript 文件
|
||||
- **THEN** 代码 SHALL 使用单引号、无分号、2 空格缩进
|
||||
- **THEN** type import SHALL 保持内联风格 `import { type Foo }`
|
||||
|
||||
#### Scenario: 格式化 JSX 代码
|
||||
|
||||
- **WHEN** 运行 `prettier --write` 格式化 JSX 文件
|
||||
- **THEN** JSX 属性 SHALL 使用单引号
|
||||
- **THEN** 多属性 SHALL 根据行宽自动换行
|
||||
|
||||
#### Scenario: 格式化 SCSS 代码
|
||||
|
||||
- **WHEN** 运行 `prettier --write` 格式化 SCSS 文件
|
||||
- **THEN** 代码 SHALL 使用 2 空格缩进
|
||||
- **THEN** CSS 规则 SHALL 保持一致的格式
|
||||
|
||||
#### Scenario: 格式化 JSON 文件
|
||||
|
||||
- **WHEN** 运行 `prettier --write` 格式化 JSON 文件
|
||||
- **THEN** JSON SHALL 使用 2 空格缩进
|
||||
- **THEN** JSON SHALL 保持尾随换行
|
||||
|
||||
#### Scenario: 格式化 Markdown 文件
|
||||
|
||||
- **WHEN** 运行 `prettier --write` 格式化 Markdown 文件
|
||||
- **THEN** 文本换行 SHALL 保持原样
|
||||
- **THEN** 代码块 SHALL 自动格式化
|
||||
|
||||
### Requirement: Prettier 忽略文件配置
|
||||
|
||||
前端 SHALL 在 `.prettierignore` 文件中配置以下忽略规则:
|
||||
|
||||
- `node_modules` — 依赖目录 SHALL NOT 格式化
|
||||
- `dist` — 构建输出 SHALL NOT 格式化
|
||||
- `dist-ssr` — SSR 构建输出 SHALL NOT 格式化
|
||||
- `bun.lock` — Bun 锁文件 SHALL NOT 格式化
|
||||
- `package-lock.json` — npm 锁文件 SHALL NOT 格式化
|
||||
- `yarn.lock` — Yarn 锁文件 SHALL NOT 格式化
|
||||
- `pnpm-lock.yaml` — pnpm 锁文件 SHALL NOT 格式化
|
||||
- `.env.*` — 环境变量文件 SHALL NOT 格式化
|
||||
- `*.local` — 本地配置文件 SHALL NOT 格式化
|
||||
- `coverage` — 测试覆盖率报告 SHALL NOT 格式化
|
||||
- `**/*.snap` — Jest snapshot 文件 SHALL NOT 格式化
|
||||
- `**/__snapshots__/**` — Jest snapshot 目录 SHALL NOT 格式化
|
||||
- `*.svg` — SVG 文件 SHALL NOT 格式化
|
||||
- `*.min.js` — 压缩的 JS 文件 SHALL NOT 格式化
|
||||
- `*.min.css` — 压缩的 CSS 文件 SHALL NOT 格式化
|
||||
- `openspec/changes/archive/` — 已归档的变更 SHALL NOT 格式化
|
||||
|
||||
#### Scenario: 不格式化依赖目录
|
||||
|
||||
- **WHEN** 运行 `prettier --write .`
|
||||
- **THEN** `node_modules` 目录 SHALL NOT 被格式化
|
||||
|
||||
#### Scenario: 不格式化锁文件
|
||||
|
||||
- **WHEN** 运行 `prettier --write .`
|
||||
- **THEN** `bun.lock` 文件 SHALL NOT 被格式化
|
||||
|
||||
#### Scenario: 不格式化测试快照
|
||||
|
||||
- **WHEN** 运行 `prettier --write .`
|
||||
- **THEN** `**/*.snap` 文件 SHALL NOT 被格式化
|
||||
- **THEN** `**/__snapshots__/**` 目录 SHALL NOT 被格式化
|
||||
|
||||
#### Scenario: 不格式化 SVG 文件
|
||||
|
||||
- **WHEN** 运行 `prettier --write .`
|
||||
- **THEN** `*.svg` 文件 SHALL NOT 被格式化
|
||||
|
||||
### Requirement: EditorConfig 配置
|
||||
|
||||
前端 SHALL 在 `.editorconfig` 文件中配置以下编辑器设置:
|
||||
|
||||
- `root = true` — 声明为根配置文件
|
||||
- `[*]` `charset = utf-8` — 所有文件 SHALL 使用 UTF-8 编码
|
||||
- `[*]` `indent_style = space` — 所有文件 SHALL 使用空格缩进
|
||||
- `[*]` `indent_size = 2` — 所有文件 SHALL 使用 2 空格缩进
|
||||
- `[*]` `end_of_line = lf` — 所有文件 SHALL 使用 Unix 换行符
|
||||
- `[*]` `insert_final_newline = true` — 所有文件 SHALL 在末尾插入空行
|
||||
- `[*]` `trim_trailing_whitespace = true` — 所有文件 SHALL 删除行尾空白
|
||||
- `[*.md]` `trim_trailing_whitespace = false` — Markdown 文件 SHALL NOT 删除行尾空白(Markdown 语法需要)
|
||||
|
||||
#### Scenario: 编辑器使用统一缩进
|
||||
|
||||
- **WHEN** 开发者在编辑器中打开项目
|
||||
- **THEN** 编辑器 SHALL 自动使用 2 空格缩进
|
||||
- **THEN** 编辑器 SHALL NOT 使用制表符缩进
|
||||
|
||||
#### Scenario: 编辑器使用统一换行符
|
||||
|
||||
- **WHEN** 开发者在编辑器中创建新文件
|
||||
- **THEN** 编辑器 SHALL 使用 Unix 换行符 (LF)
|
||||
- **THEN** 编辑器 SHALL NOT 使用 Windows 换行符 (CRLF)
|
||||
|
||||
#### Scenario: 编辑器使用统一编码
|
||||
|
||||
- **WHEN** 开发者在编辑器中保存文件
|
||||
- **THEN** 文件 SHALL 使用 UTF-8 编码保存
|
||||
|
||||
### Requirement: VS Code 扩展推荐
|
||||
|
||||
前端 SHALL 在 `.vscode/extensions.json` 文件中推荐以下扩展:
|
||||
|
||||
- `esbenp.prettier-vscode` — Prettier 格式化扩展
|
||||
- `dbaeumer.vscode-eslint` — ESLint 检查扩展
|
||||
|
||||
#### Scenario: VS Code 提示安装扩展
|
||||
|
||||
- **WHEN** 开发者使用 VS Code 打开项目
|
||||
- **THEN** VS Code SHALL 提示安装推荐的扩展
|
||||
- **THEN** 推荐列表 SHALL 包含 Prettier 和 ESLint 扩展
|
||||
|
||||
### Requirement: VS Code 格式化设置
|
||||
|
||||
前端 SHALL 在 `.vscode/settings.json` 文件中配置以下设置:
|
||||
|
||||
- `editor.formatOnSave = true` — 保存时 SHALL 自动格式化
|
||||
- `editor.defaultFormatter = "esbenp.prettier-vscode"` — 默认格式化器 SHALL 为 Prettier
|
||||
- `editor.codeActionsOnSave.source.fixAll.eslint = "explicit"` — 保存时 SHALL 自动修复 ESLint 问题
|
||||
|
||||
#### Scenario: 保存时自动格式化
|
||||
|
||||
- **WHEN** 开发者在 VS Code 中保存文件
|
||||
- **THEN** 文件 SHALL 自动使用 Prettier 格式化
|
||||
- **THEN** ESLint 可修复的问题 SHALL 自动修复
|
||||
|
||||
#### Scenario: 使用 Prettier 作为默认格式化器
|
||||
|
||||
- **WHEN** 开发者在 VS Code 中使用格式化命令
|
||||
- **THEN** SHALL 使用 Prettier 进行格式化
|
||||
- **THEN** SHALL NOT 使用其他格式化器
|
||||
|
||||
### Requirement: Prettier 与 ESLint 集成
|
||||
|
||||
前端 SHALL 在 `eslint.config.js` 中导入 `eslint-config-prettier` 配置,关闭与 Prettier 冲突的 ESLint 规则。
|
||||
|
||||
#### Scenario: ESLint 配置集成 Prettier
|
||||
|
||||
- **WHEN** 配置 `eslint.config.js`
|
||||
- **THEN** SHALL 导入 `eslint-config-prettier`
|
||||
- **THEN** `eslint-config-prettier` SHALL 放在配置数组的最后
|
||||
- **THEN** 与 Prettier 冲突的 ESLint 规则 SHALL 被关闭
|
||||
|
||||
#### Scenario: ESLint 与 Prettier 不冲突
|
||||
|
||||
- **WHEN** 运行 `eslint .` 和 `prettier --check .`
|
||||
- **THEN** ESLint 检查和 Prettier 格式化 SHALL NOT 产生冲突
|
||||
- **THEN** 同一文件 SHALL NOT 同时报告 ESLint 错误和 Prettier 格式问题
|
||||
|
||||
### Requirement: 格式化脚本配置
|
||||
|
||||
前端 SHALL 在 `package.json` 中配置以下脚本:
|
||||
|
||||
- `format = "prettier --write ."` — 格式化所有文件
|
||||
- `format:check = "prettier --check ."` — 检查文件格式
|
||||
- `check = "bun run lint && bun run format:check"` — 检查 lint 和格式
|
||||
- `fix = "bun run lint:fix && bun run format"` — 修复 lint 问题并格式化
|
||||
|
||||
#### Scenario: 运行格式化命令
|
||||
|
||||
- **WHEN** 执行 `bun run format`
|
||||
- **THEN** SHALL 运行 `prettier --write .`
|
||||
- **THEN** 所有文件 SHALL 被格式化
|
||||
|
||||
#### Scenario: 运行格式检查命令
|
||||
|
||||
- **WHEN** 执行 `bun run format:check`
|
||||
- **THEN** SHALL 运行 `prettier --check .`
|
||||
- **THEN** 未格式化的文件 SHALL 报告错误
|
||||
|
||||
#### Scenario: 运行统一检查命令
|
||||
|
||||
- **WHEN** 执行 `bun run check`
|
||||
- **THEN** SHALL 运行 `bun run lint && bun run format:check`
|
||||
- **THEN** lint 错误和格式问题 SHALL 都被检查
|
||||
|
||||
#### Scenario: 运行统一修复命令
|
||||
|
||||
- **WHEN** 执行 `bun run fix`
|
||||
- **THEN** SHALL 运行 `bun run lint:fix && bun run format`
|
||||
- **THEN** lint 问题 SHALL 被修复
|
||||
- **THEN** 文件 SHALL 被格式化
|
||||
|
||||
### Requirement: Prettier 依赖安装
|
||||
|
||||
前端 SHALL 安装以下依赖:
|
||||
|
||||
- `prettier` — Prettier 核心库
|
||||
- `eslint-config-prettier` — 关闭与 Prettier 冲突的 ESLint 规则
|
||||
|
||||
#### Scenario: 安装 Prettier 依赖
|
||||
|
||||
- **WHEN** 执行 `bun install`
|
||||
- **THEN** `prettier` SHALL 被安装
|
||||
- **THEN** `eslint-config-prettier` SHALL 被安装
|
||||
- **THEN** 依赖版本 SHALL 在 `package.json` 中声明
|
||||
Reference in New Issue
Block a user