我如何规划与落地组件库

本文是 Kotodama UI(@kotodama/lego-react)的规划与落地说明:解决什么问题、如何分期、技术如何选型、代码如何长在仓库里。
叙事札记版见博客:我为什么自研一套 React + Lego 组件库

1. 要解决什么问题

成品「全家桶」UI 库(以开源 Ant Design 为代表)在下列维度成本偏高,构成本库的问题陈述:

痛点 对本库的含义
设计语言刚性,深定制贵 同时服务企业后台品牌 / 营销站,视觉不能绑死蓝白中后台气质
CSS-in-JS / 重组件性能税 样式栈自控;列表 / 表格场景可瘦身
rc-* / @rc-component/* 跨仓深 不使用 rc-component;交互原语自研或可控白名单
PC / 移动生态割裂(antd vs antd-mobile) 一套组件 + 自适应样式,不做第二套 mobile-only 库
对 AI / 低代码不友好 组件可描述、可装配;远期产出 LLM 可读契约文件

结论: 优先「可扩展积木 + 多场景皮肤」,而不是「复制 antd 组件数量」。

四类目标场景(需求 §4):

  1. 企业后台:表单、表格、导航、反馈、密度与基础 a11y
  2. 品牌营销站:Hero、卖点、CTA、留资、换肤与首屏性能
  3. 品牌内容站:导航 / 页脚 / 排版 / SEO 友好结构
  4. 自适应移动端:同一套组件 + 断点 / 触控 / 安全区,而不是另起库

工程硬约束(需求 §5.3):组件库为仓库内独立子项目,与 platform/landing/ 目录 / 依赖 / 构建 / 运行时隔离;唯一接点为 Header 外链 + 网关静态挂载 /ui/

2. 怎么规划

2.1 架构原则

  1. 积木优先:扩展靠 wrappers / intercepters / 组合,不靠无限加 props
  2. 场景分层primitivespatternsblocks,依赖单向向下
  3. 样式与逻辑分离:逻辑层不假设 antd 视觉;主题可替换
  4. 一份契约,多种皮肤:后台与品牌站共享 API;皮肤与密度可切换
  5. 为跨平台留纯逻辑边界:listeners 保持纯;副作用集中在适配层
  6. 为 LLM 留描述边界:稳定公开面(props / state / 场景 / 反模式)

2.2 分期(S0–S3)

阶段 目标
S0 独立子项目骨架 + Lego 规范 + Token + 门禁 + Button/Input/Layout;Rspress + /ui/
S1 后台主路径(Form / Table / Nav / Feedback)+ 后台 Demo A
S2 品牌 / 营销 blocks + 响应式 + 营销 Demo B
S3 元数据 → LLM 文件 v0;SSR / 静态样式加固
S4+ 跨平台工具 PoC;AI recipes(非本期)

本期 MVP 明确不做:antd/rc 封装、大而全复制、原生 App 运行时、完整低代码编辑器、与 antd API 兼容、把文档做进 platform SPA。

2.3 成功标准(摘要)

  • CI 依赖门禁:无 rc-component / rc-* / @rc-component/*
  • 独立子项目:不构建组件库时现网仍可运行
  • Demo A(后台列表 + 表单)与 Demo B(Hero + 卖点 + CTA + 移动自适应)
  • 同一 Button/Input 在 admin / brand 下气质不同、API 一致
  • Rspress /ui/ + wrappers 可运行示例
  • 组件元数据覆盖 MVP ≥ 80%

3. 技术如何选型

定案 说明
框架 React 18+ 主交付形态为 React 组件
编写规范 Lego Modules state / listeners / render / wrappers / intercepters;对外 wrap 成常规组件
底层交互 零 rc-component CI check:no-rc 扫描依赖与源码 import
样式 CSS Variables + 静态 CSS data-theme / data-density;避免强制运行时 CSS-in-JS
主题 admin / brand / dark brand 默认亮色营销面;暗色宿主走 brand 暗色面(暖金),不吞成 admin dark
文档站 Rspress 静态导出挂 /ui/;Storybook 可选并行
工程 design-system/ 自有 pnpm workspace;与 platform 三套依赖并存属有意隔离
@kotodama/tokens + @kotodama/lego-react 分层 exports:primitives / patterns / blocks / meta

明暗与 Demo 纪律:文档站壳与组件库 Token 是两套电;嵌在文档里的活示例必须通过 DocsDemoProvider 跟随 Rspress 明暗。营销 Demo 在亮色用 brand 亮面、暗色仍用 brand(暗色面),全局主题切换才有意义。相关踩坑见博客「文档站暗了,Demo 还亮着」。

4. 实际代码如何落地

4.1 仓库形态

design-system/
  package.json                 # build / check:no-rc / test / typecheck
  scripts/check-no-rc.mjs
  scripts/check-meta-coverage.mjs
  packages/
    tokens/                    # Design Token(CSS Variables)
    react/                     # @kotodama/lego-react
      src/lego/createComponent.tsx
      src/primitives|patterns|blocks/
      src/meta/                # schema + LLM 导出
  apps/docs/                   # Rspress → base /ui/
.github/workflows/design-system.yml

接点(现网侧,已约定):

  • landing Header → /ui/
  • docker/nginx.ui-example.conf 静态挂载示例
  • 默认 Compose 捆绑组件库构建

4.2 Lego 写法(定案)

外壳:ConfigProvider / mergePropsWithConfig / 公开 XxxProps
内核:createComponentstate / listeners / render;示范处挂 wrappers

import {
  createButtonWithWrappers,
  createHeroWithWrappers,
} from '@kotodama/lego-react';

const BadgeButton = createButtonWithWrappers([
  (node) => (
    <span className="wrap">
      <span className="badge">New</span>
      {node}
    </span>
  ),
]);

可运行示例见 Lego wrappers

4.3 主题与样式

  • Token 包驱动 [data-theme="admin"|"brand"|"dark"];brand 另有 html.dark / data-scheme="dark" 暗色面
  • 组件样式稳定类名 kd-*,构建产物 style.css 与分层 primitives.css / patterns.css / blocks.css
  • SSR:显式引入 CSS;模块顶层禁止 document / window(见 SSR

4.4 工程化与验收

能力 命令 / 位置
禁止 rc pnpm check:no-rc
类型 pnpm typecheck
测试 pnpm test(Vitest + RTL:Button / Form / Table / createComponent)
元数据覆盖率 pnpm check:meta-coverage(需先 build:packages
构建 pnpm build:packages / pnpm build:docs
CI .github/workflows/design-system.yml(仅 design-system/**,不阻断 platform)

场景验收:

4.5 Agent / LLM 埋点

  • componentMetaList(props、scenes、antipatterns…)
  • 构建导出 @kotodama/lego-react/meta/llm/components.json(及 yaml)
  • 说明见 组件元数据 / LLM

5. 从这里继续

文档 用途
快速开始 安装与按层引入
主题切换 admin / brand / dark
Lego wrappers 换皮扩展路径
响应式 断点、触控、安全区

组件库的目标不是多一个 npm 包,而是让后台效率、品牌表达、移动自适应、以及将来的 AI 装配共用一份契约、多种皮肤——并从第一天起不踩现网的脚。