在上一篇文章中,我们分享了“领域驱动+技术栈驱动”的规则体系结构,解决了AI检索与人类维护的双重问题。但随着团队规模扩大(从3个项目增至12个),新的痛点浮出水面:通用规则在业务项目中“水土不服”,业务定制规则又容易打破技术底线——比如金融项目需要特殊的精度计算规范,却不能违背TypeScript的类型安全原则。
本文要拆解的 “洋葱圈三层架构” ,正是为解决这个矛盾而生。它让规则像代码一样支持“继承”与“重写”,既守住通用标准的底线,又给足业务定制的灵活度。
核心价值:这套架构让我们的规则复用率从40%提升至75%,跨项目规则调整时间从1天缩短至2小时——关键在于明确了“哪些规则不能动”“哪些规则可定制”的边界。
一、为什么需要“洋葱圈”?规则体系的扩展性困境
在没有分层架构前,我们踩过两次致命的坑,这也是很多团队的共性问题:
- 通用规则“一刀切” :把“所有组件用PascalCase命名”的通用规则强推给金融项目,却忽略了该项目因对接老系统,部分组件必须用下划线命名——最终要么违规开发,要么重构老系统,成本极高;
- 业务规则“乱开花” :电商项目为了快速上线,自定义了“允许any类型简化开发”的规则,后续与通用规则合并时,引发200+类型错误,排查了整整3天。
本质问题是“规则边界模糊”——没有明确区分“必须遵守的底线”和“可以调整的细节”。而“洋葱圈三层架构”的核心逻辑,就是用分层明确边界,外层依赖内层,内层约束外层,同时支持外层对中层的“扩展”和对核心层的“兼容”。
二、洋葱圈三层架构:从核心到应用的规则体系
整个架构像一颗洋葱,从内到外分为“核心基石层-领域业务层-项目应用层”,层级越靠内,规则优先级越高、通用性越强;层级越靠外,定制化程度越高、适用范围越窄。
1. 核心基石层(最内层):不可动摇的技术底线
对应目录 rules/core/,是所有项目的“技术宪法”,定义“无论什么业务都不能打破的规则”,由架构团队统一维护,任何人无权修改。
- 核心定位:保障技术栈的统一性、代码的可维护性和系统的安全性,是规则体系的“压舱石”;
- 覆盖范围:TypeScript基础语法(如“禁止隐式any”)、Git提交规范(如“提交信息必须包含类型+模块”)、代码格式标准(如“缩进2空格”)、安全底线(如“XSS防护必做”);
- 落地特点:所有项目强制生效,不允许任何形式的重写,只能被外层规则“扩展”;
- 示例文件:
typescript-standards.md(TS类型规范)、security-xss.md(XSS防护标准)。
2. 领域业务层(中间层):业务线的定制化扩展
对应目录 rules/domain/,是某类业务线或技术栈的“通用规范”,由业务架构师维护,可基于核心层规则进行“扩展”,但不能违背核心层。
这一层又分为“公共资源规范”和“业务模式规范”两类:
- 公共资源规范:公司级通用资产的使用规则,比如“公共组件库必须按设计token配色”“通用Hooks必须返回固定格式”——确保跨项目使用时体验一致;
- 业务模式规范:特定业务的专属规则,比如金融业务的“金额计算必须用BigDecimal,禁止浮点数”、SaaS业务的“多租户数据必须隔离存储”——解决业务特性带来的特殊需求。
落地特点:仅对对应业务线的项目生效,优先级高于核心层(可补充核心层未覆盖的规则),但核心层规则仍起约束作用;
示例文件:finance-calculation.md(金融计算规范)、common-hooks-patterns.md(通用Hooks模式)。
3. 项目应用层(最外层):单个项目的灵活适配
对应目录 rules/project/,是某一个具体项目的“特殊约定”,由项目负责人维护,可基于核心层和领域层进行“重写”,优先级最高。
- 核心定位:解决单个项目的“特例问题”,避免为了适配项目而修改核心层或领域层规则;
- 覆盖范围:项目专属的目录结构(如“老项目改造时保留legacy目录”)、第三方工具的特殊配置(如“对接某支付接口的加密规则”);
- 落地特点:仅对当前项目生效,优先级最高(可重写外层规则),但必须在文档中明确“重写原因”,便于后续迭代。
三、关键实现:让AI也懂的“继承与重写”机制
分层架构的核心是“规则间的依赖关系”,我们通过在规则文件的Frontmatter中增加priority(优先级)和extends(继承)字段,让AI和开发者都能清晰识别规则的关联。
优先级规则:项目应用层(300+)> 领域业务层(200+)> 核心基石层(100),数值越高,规则优先级越高。
实战示例:业务组件如何扩展核心组件规则
假设核心层定义了Vue3组件的基础规范,领域层需要在此基础上增加业务组件的特殊要求,具体实现如下:
1. 核心基石层规则(不可修改)
文件路径:rules/core/vue3-component.md
---
id: core-component
priority: 100 # 核心层固定优先级100
scope: all-projects # 所有项目生效
---
## Vue3组件核心规范
1. 组件文件名必须使用 PascalCase(如 UserCard.vue);
2. 组件props必须定义类型,禁止省略;
3. 禁止在模板中直接操作DOM。
2. 领域业务层规则(继承并扩展)
文件路径:rules/domain/business-components.md(仅金融业务线生效)
---
id: biz-component
priority: 200 # 领域层优先级高于核心层
extends: core-component # 明确继承核心层组件规则
scope: finance-projects # 仅金融项目生效
---
## 金融业务组件扩展规范
基于 core-component 规则,新增以下要求:
1. 所有业务组件必须继承 BaseBusinessCard 组件(统一业务组件基础样式);
2. 必须包含 businessId prop(关联业务数据唯一标识);
3. 金额展示必须调用 formatMoney 工具函数(统一金额格式)。
# 说明:核心层的"PascalCase命名"等规则仍需遵守,此处仅做扩展
3. 项目应用层规则(重写特例)
文件路径:rules/project/finance-old-system.md(某金融老项目改造专用)
---
id: old-system-component
priority: 300 # 项目层优先级最高
extends: biz-component # 继承领域层规则
scope: finance-old-system # 仅当前老项目生效
override: core-component#1 # 明确重写核心层第1条规则
---
## 老项目组件适配规范
1. 【重写核心层】对接老系统的组件文件名允许使用 kebab-case(如 user-card.vue),新开发组件仍用 PascalCase;
2. 【继承领域层】必须继承 BaseBusinessCard 并包含 businessId prop;
3. 新增:老系统组件需添加 legacy 标签(便于后续识别改造)。
# 重写原因:老系统有100+组件为kebab-case,全量修改成本过高,暂做兼容
当AI检索规则时,会根据项目所属范围(finance-old-system)自动识别优先级,优先应用项目层规则,再叠加领域层和核心层未被重写的规则——既满足了老项目的特殊需求,又守住了大部分技术规范。
四、落地关键:公共基础设施的规则映射表
在实际业务中,公共资源是规则冲突的高发区。我们整理了“公共基础设施-规则目录-约束与扩展点”的映射表,让每个资源的规则边界一目了然,AI和开发者都能快速定位。
| 公共资源类型 | 项目中对应目录 | 核心约束规则(核心层) | 业务扩展点(领域/项目层) |
|---|---|---|---|
| 公共工具函数 | src/utils | 1. 必须包含TS类型定义;2. 函数单一职责;3. 异常需抛出自定义错误 | 1. 金融项目:金额相关工具需支持BigDecimal;2. 国际化项目:新增多语言格式化函数 |
| 通用Hooks | src/composables | 1. 命名以use开头(如useRequest);2. 返回值为对象便于解构;3. 依赖项完整声明 | 1. 电商项目:useCart Hooks需包含库存校验;2. 后台项目:useTable Hooks需支持批量操作 |
| UI组件库 | src/components/common | 1. 基于Element Plus二次封装;2. 支持size/color等基础属性;3. 抛出统一事件格式 | 1. 金融项目:按钮新增风险等级配色(红色为高危操作);2. 移动端项目:组件适配小屏触控 |
| 全局类型定义 | src/types | 1. 类型命名用PascalCase;2. 接口用interface,类型别名用type;3. 禁止使用any | 1. 金融项目:新增Amount类型(基于BigDecimal);2. 多租户项目:新增TenantInfo类型 |
五、快速落地:Vue3项目的领域层规则注入示例
为了让大家快速上手,我们在examples/vue3-demo中搭建了完整的分层规则示例,核心步骤如下,可直接复用:
- 1. 初始化规则目录在项目根目录创建
.windsurf/rules,并按三层架构创建子目录:.windsurf/rules/ `` ├── core/ # 核心层规则(从架构库复制) `` │ └── vue3-component.md `` ├── domain/ # 领域层规则(金融业务线) `` │ └── finance-components.md `` └── project/ # 项目层规则(当前项目) ``└── old-system-adapt.md - 2. 配置规则解析器在
scripts/rule-parser.js中新增“按优先级合并规则”的逻辑,确保高优先级规则覆盖低优先级:// 新增:合并多规则文件,按priority排序 `` mergeRules(rules) { `` // 按优先级从高到低排序 `` const sortedRules = rules.sort((a, b) => b.priority - a.priority); `` // 合并规则内容,高优先级覆盖低优先级 `` return sortedRules.reduce((result, rule) => { `` // 处理重写:如果有override字段,只保留未被重写的规则 `` if (rule.override) { `` const [targetId, targetIndex] = rule.override.split('#'); `` const targetRule = result.find(r => r.id === targetId); `` if (targetRule) { `` targetRule.content = targetRule.content.replace( ``` new RegExp(({targetIndex}\. .+)`), ```` `// 被{rule.id}重写:{rule.content}``` ); `` } `` } else { `` result.push(rule); `` } `` return result; `` }, []); ``} - 3. 集成到CI/CD在GitHub Actions中新增“规则校验”步骤,确保代码符合当前项目的规则组合:
# .github/workflows/rule-check.yml `` - name: 规则校验 `` run: node scripts/rule-validator.js `` env: `` PROJECT_SCOPE: finance-old-system # 指定项目范围,自动匹配规则 ``RULES_DIR: .windsurf/rules
六、总结:规则体系的“不变”与“变”
洋葱圈三层架构的本质,是在规则体系中明确了“不变的底线”和“可变的空间”:
- 不变的:核心基石层的技术标准,确保跨项目的一致性和安全性;
- 可变的:领域层的业务扩展和项目层的特殊适配,满足不同场景的定制需求。
这种设计不仅让规则体系更具生命力,也让AI能更精准地匹配规则——当开发者问“金融项目的Vue组件怎么写”时,AI会自动组合“core+domain+project”三层规则,给出既符合技术标准又适配业务需求的答案。
互动讨论:你的团队在规则定制中遇到过哪些冲突?是如何平衡通用与特殊需求的?欢迎在评论区分享你的解决方案!