1
0
Files
nex/openspec/specs/frontend-lint-rules/spec.md

141 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 前端 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 重复检查同一规则