📄 本页由源文件
rules/开发规范-红线.mdc自动投影生成(单一权威源)。请勿直接编辑本页。
开发规范-红线
<!-- 📌 本文件定位:alwaysApply 红线规范,每次对话都会加载,直接消耗上下文窗口。 ⚠️ 准入标准:①违反即出事的硬性禁令 ②每次编码都必须遵守的底线 ③1-3行能说清 🎯 目标:≤80行,只留"不看会出问题"的内容。参考信息已迁移到 dev-flow Skill。 -->
本规则为最高优先级红线。详细规范通过 dev-flow skill 按需加载。
操作红线
- 严禁擅自
git commit/git push/修改.git配置(commit 只能生成信息) - 严禁在公共/共享分支上直接提交代码;误操作后须按场景用 stash/cherry-pick 搬移改动,禁止 merge 公共分支(详见
skills/dev-flow/references/shared-rules.md§7.1) - 严禁删除重要文件、修改项目配置(除非用户要求)、主动创建文档文件
- Commit 格式:
<type>: <description>(无 scope,不加括号) - 新增代码质量底线:发现老代码缺陷必须在新代码中修正,禁止延续缺陷
核心原则(12 条红线)
- 需求理解优先——禁止猜测,不确定点汇总确认,99% 把握再执行
- 最小入侵——保持原有逻辑,只追加必要新逻辑;禁止为单次使用的代码做抽象,禁止添加未被要求的灵活性/可配置性;发现无关缺陷/死代码→提及但不擅自修改;自己的改动导致的孤儿导入/变量/函数→主动清理;自检:每行变更必须可追溯到用户请求
- 兼容性优先——不确定时主动查询 MDN/Can I Use
- 根因定位与验证闭环——禁止盲改;先定位根因再修复;改完必须验证
- 安全底线——禁止拼接 SQL/HTML,禁止硬编码密钥/token
- 副作用必须清理——useEffect 必须 cleanup;卸载后禁止 setState
- 边界条件与防御性编码——处理空值/undefined/空数组/异常输入;所有链式属性访问必须使用可选链
?.(如response?.data?.items?.length),禁止裸链式访问;无论值来源(props/state/回调参数/守卫后分支),均无例外;增量更新时优先优化本次改动行涉及的链式调用,同函数内的其他链式调用建议一并优化 - 异步与竞态安全——并发请求处理竞态;异步有 loading/error/success 三态;useEffect 中异步操作必须处理组件卸载场景(cleanup 取消/忽略结果)
- 错误处理——禁止空 catch 吞异常;组件树用 Error Boundary 兜底
- 先搜索后编码——新增工具函数/组件/Hook 前必须先搜索项目已有实现并确认可直接使用,有则复用(不改造原代码),无则再新建
- 主动思考更优方案——执行时必须思考是否有更好实现;发现更优方案及时建议;禁止机械执行
- 上下文管理——不相关任务开新对话;长对话用 TODO 持久化;遗忘时重读 working-context
前端编码底线(每次写代码必须遵守)
TypeScript / JavaScript
const优先,需重新赋值用let,禁止var- 严格全等
===/!==,禁止==/!= - 禁止
any,用unknown+ 类型守卫;接口返回值必须定义明确类型 - 解构优先:
const { name, age } = user,禁止反复user.name - 字符串用模板字面量,禁止
+拼接 - 数组操作返回新实例(
map/filter/展开),禁止原地push/splice修改源数组(纯函数场景) - 禁止嵌套三元表达式:≥2 层三元嵌套必须拆分为
if早返回或独立变量;单层三元仅在逻辑极简时允许(如x ? A : B) - 分号前禁止空格:
290;正确,290 ;错误(违反semi-spacing规则) - 复杂参数/条件必须提取为命名变量:函数调用中的多行三元表达式、多分支条件对象必须提取为独立的命名变量(如
externalParam/orgParam),禁止内联在函数参数中;多函数共用的对象构造逻辑必须抽取为公共工厂函数
React
- 组件用函数式 + Hooks,禁止新增 class 组件
useEffect必须 cleanup(定时器/订阅/事件监听);依赖数组禁止盲加,先分析变量会不会变- 状态更新依赖前值时用函数式:
setState(prev => prev + 1) - 避免不必要的重渲染:合理使用
React.memo/useMemo/useCallback - JSX 布尔属性用花括号:
bordered={false},禁止bordered="false" - JSX 内禁止复杂表达式:JSX props 中的条件逻辑超过单层三元时,必须提取为
useMemo变量或组件顶部的const;useState初始值含条件逻辑时用惰性初始化useState(() => { ... }) - useEffect 内多分支重复逻辑必须提取:多个条件分支中重复的
setState/ref 赋值/回调调用必须提取到分支外统一执行;差异部分用变量(如expandId)承接,公共部分在分支后一次性处理 - 异步 try-catch 用
finally统一清理状态:setLoading(false)等清理操作禁止在 try 和 catch 中各写一份,必须用finally统一处理
CSS / SCSS
- 缩进 2 空格;选择器后必须有空格(
.class {非.class{) - 禁止
!important(除非覆盖第三方 JS 内联样式且无组件 API 可用) - 嵌套不超过 3 层;禁止用标签选择器(
div/span)做业务样式 - 颜色/间距/字号优先使用项目 CSS 变量(
var()),禁止硬编码魔法值
依赖管理
- 安装依赖前先检查 lock 文件现有版本,禁止盲目升级
- 禁止修改 lock 文件格式版本(如 lockfileVersion)
- 新增依赖必须说明用途,优先选已在项目中使用的包
- 💡 版本映射表、安装检查清单、恢复方法等详细操作 → 按需规则
依赖管理与Lock文件规范
编码完成必检(每次编码后强制执行,含迭代修复)
- 步骤 5.5 不可跳过:dev-flow 中每轮编码(含迭代修复、步骤 5 内部多轮修复)完成后,必须执行步骤 5.5(5.5a L1 审查 + 5.5b 文档同步 + 5.5c ESLint 自检),不得跳过直接向用户汇报完成;用户主动要求"生成 commit"或"代码审查"时,若 5.5 未执行,必须先补执行 5.5 再继续
- L1 审查 = 完整 8 项检查:ESLint 命令行、可选链、浏览器兼容性、React 规范、CSS 规范、异步竞态、边界条件、通用检查(调试代码/未使用 import)
read_lints≠ ESLint:IDE 的read_lints只检查 TypeScript 类型错误,不覆盖 ESLint 规则(如import/no-duplicates、arrow-parens、max-len、no-param-reassign);两者都必须执行- 迭代修复不豁免:无论是首次开发还是第 N 轮迭代修复,每轮编码完成后都必须执行 L1 审查,不因"改动小"而跳过
无 dev-flow 直接改代码(精要)
- 仍守本文件 12 条核心红线 + 前端编码底线
- 必跑
read_lints+ 改动行 ESLint,不得自动 commit - 改动 ≥4 文件 / ≥30 行 / 涉及核心模块 → 主动建议改用
dev-flow命令 - 详细规则 →
skills/dev-flow/references/no-dev-flow-mode.md