block重名必然发生,需用子系统前缀(如crm-contact-card)替代临时补丁,统一注册至blocks.json,并在html、scss、js全链路强制使用,确保语义隔离与可追溯。

Block 重名不是“会不会发生”的问题,而是“什么时候暴露”的问题——只要没建索引、没进 CI 校验,它就在 CSS 规则表里静默覆盖,直到某天 .user-card__avatar 的 margin 突然失效,而 DevTools 里两个同名类并排躺着,加载顺序都得手动翻 source。
为什么子系统前缀比“加个字母”更可靠
单纯在 user-card 前加 pc- 或 mobile- 是临时补丁,不是隔离方案。真正要防的是语义重叠:比如 CRM 系统的 contact-card 和客服系统里的 contact-card,功能相似但字段、交互、权限完全不同。子系统前缀(如 crm-contact-card、cs-contact-card)把业务域直接编码进 Block 名,让冲突可识别、可追溯、可搜索。
- 前缀必须是已知子系统标识,不能是设备类型(
mobile-)、环境(dev-)或临时版本号(v2-) - 前缀长度控制在 2–4 字符,过长导致类名膨胀,过短易歧义(
c-是 chat 还是 customer?) - 所有子系统前缀需统一注册进
blocks.json,例如{"crm-contact-card": "CRM 客户联系人卡片", "cs-contact-card": "客服会话中联系人信息浮层"}
子系统前缀和 BEM 三段式怎么共存不打架
BEM 的 block__element--modifier 结构不变,前缀只是 block 名的一部分。关键在于:前缀必须参与整个命名链,不能只加在 HTML class 上而 SCSS 里漏掉。
- 正确:
crm-contact-card__avatar、crm-contact-card--compact、cs-contact-card__avatar - 错误:
contact-card__avatar(漏前缀)、crm-contact-card__avatar--small(Modifier 不该跨子系统复用) - SCSS 中必须用完整 Block 名定义嵌套:
.crm-contact-card { &__avatar {} &--compact {} },不能写成.contact-card { &__avatar {} }再靠 wrapper class 补前缀
哪些场景下子系统前缀会失效
前缀不是银弹。当两个子系统共享同一套 UI 组件库(比如都用 @company/ui),而库内 Block 名没带前缀时,项目级前缀就拦不住冲突。
- 第三方组件库的 Block 名必须强制要求带组织/平台前缀,如
cmp-button、cmp-modal,不能接受裸名button - 微前端架构下,子应用独立构建,需在构建时注入运行时前缀变量,避免硬编码导致热更新后类名不匹配
- 设计系统文档中,每个 Block 示例必须标注适用子系统,禁止写“通用卡片”,而应写“适用于 CRM 和 BI 子系统的数据卡片基座(
crm-data-card/bi-data-card)”
最常被忽略的一点:子系统前缀一旦启用,就不能只在 CSS 里加,JS 中的 querySelector、classNames、测试断言也得同步改——否则 document.querySelector('.user-card__name') 会永远返回 null,而你查半天才发现 HTML 里实际是 crm-user-card__name。










