在大型 React 项目中,多个业务线或团队常需共享 UI 和工具能力。建立内部组件库和公共能力层是避免重复造轮子、统一体验、提升效率的长期投资。这一节聚焦如何落地。
组件库的定位与边界
组件库不是简单的“把公共组件扔到一个文件夹”。它应是独立维护、版本化管理、有清晰接口契约的软件包。首先要界定范围:
- UI 组件库:按钮、弹窗、表格、表单控件等无业务含义的通用 UI 组件。
- 业务组件库:带固定业务逻辑的模块,例如顶栏导航、特定表单区块,供多个应用复用。
- 工具函数库:
formatDate、request封装、自定义 Hooks(如usePermission)等纯逻辑能力。
三个层次可分别建包,独立迭代,避免捆绑升级。
组件设计原则
- 单一职责
一个组件只做一件事。大型应用中最怕“万能组件”——上百个 Props 控制各种内部分支,维护噩梦。
例如,Table 负责结构,通过 columns 配置列,表格行内的按钮通过插槽或 renderCell 由使用方决定,组件自身不问业务含义。
- 一致性优先
设计统一的 Props 命名规范:disabled、size、variant、onChange 等,避免此处的 enable 对应彼处的 disabled。
全局主题变量(颜色、字号、间距)通过 CSS 变量或 Context 注入,确保跨组件视觉统一。
- 可组合而非继承
优先用组合实现变体。例如 Dialog 提供 Header、Body、Footer 子组件,而不是通过一百个 Props 配置所有内容。
- 最小惊讶原则
行为符合原生 HTML 惯例。例如,自定义 Input 应该支持 ref 转发,onChange 直接传递原生事件,避免学习成本。
- 稳定性与版本管理
公共组件一旦发布,破坏性变更需通过 major 版本号 + 详细的升级指南。建议使用语义化版本,并提供 CHANGELOG。
工程化落地要点
- 独立仓库(Monorepo 更佳)
将组件库放在独立仓库或 pnpm workspaces / turborepo 的包中。好处是可单独发版,CI 独立,测试用例专门维护。Monorepo 允许应用和库在同一仓库联调,降低修改成本。
- 构建与输出
输出格式至少支持 ESM 和 CJS。使用 Rollup 或 tsup 打包,配置 peerDependencies 将 react、react-dom 标记为外部依赖,避免打包进库。
需要输出 TypeScript 类型定义(.d.ts),供使用方享受智能提示。
- 文档体系
用 Storybook 搭建交互式文档,每个组件至少提供:
- 基本示例 + 代码
- Props 表格
- 边界案例(空数据、长文本、加载态、错误态)
文档是组件库的“门面”,也是团队的沟通语言。
- 测试策略
单元测试用 React Testing Library 覆盖交互行为,快照测试可辅助但不应依赖。视觉回归测试(如 Chromatic)可捕捉意外样式变更。
- 主题与定制
大型产品往往存在不同品牌或主题,组件库应支持主题化。可以实现:
- CSS 变量 + 数据属性切换
- 基于
Context的 ThemeProvider,注入 tokens - 组件本身只消费 tokens,不写死颜色值
- 按需加载与 Tree Shaking
确保组件库支持 ES Modules 引入,使用者可以 import { Button } from 'lib' 而无需引入整个库。打包工具会自动 tree-shake。避免在入口文件使用副作用导入(如全局样式一次性导入),可提供一个轻量的“按需加载”方案或 CSS 变量方案。
公共能力沉淀
除 UI 外,大量非视觉逻辑也需要沉淀:
- 自定义 Hooks 库
如 useDebounce、useRequest、useLocalStorage、usePermission。这些 Hooks 封装了通用状态与副作用逻辑,可跨项目复用。同样遵循独立包、测试、版本化管理。
- 工具函数
日期格式化、数字千分位、数据验证等纯函数,集中维护,搭配文档。
- 请求层封装
将对 Axios 或 fetch 的二次封装(拦截器、错误处理、token 刷新)抽象为内部库,统一所有应用的网络请求行为。
- 业务配置与常量
多项目共用的枚举值、权限码、环境配置,可集中管理,避免散落各处造成不一致。
组件库推进的实践经验
- 渐进式建设
初期不必追求完美,从实际最复用的 2-3 个组件开始,逐步丰富。一味铺量会导致大量低频组件无人维护。
- 强制复用与自治平衡
可以采用“默认使用公共组件库”的规范,但给予业务团队提交 PR 完善组件库的通道,贡献者即维护者,形成共建文化。
- 样式隔离
避免全局样式污染,采用 CSS Modules、CSS-in-JS 或 BEM 命名,确保引入组件库时不影响原有页面布局。更优方案是封装为 Web Components 的影子 DOM,但 React 生态下较少用。
- 兼容性声明
明确支持的 React 版本范围,以及浏览器最低兼容要求。每当升级 React 时,库需同步调整。
组件库和公共能力层的价值不是短时间内可量化的,但它决定了一个长周期、多团队产品的技术健康度。投入扎实的工程化基建,最终会反哺为更少 Bug、更快交付和更一致的用户体验。