前言
最近公司需要搭建一个自己的业务组件库,记录一下自己的搭建过程。
没想到已经 2025 年了,做一个组件库还是那么费劲,一路踩了无数的坑,苦也 😢
方案调研
首先我们项目的技术栈是:react
+ typescript
+ arco design
+ tailwindcss
,目标是能同时生成 组件库站点 与 npm 包。
在翻阅不少资料以后,基本只看到了两个推荐:storybook 与 dumi。
storybook | dumi | |
---|---|---|
star 数 | 87k ⭐️ | 3.7k ⭐️ |
支持框架 | 大部分框架 | react |
文档 | 官方仅英文 | 中文 |
学习成本 | 高 | 简单 |
更新频率 | 高 | 低 |
综合来看,还是 storybook 更胜一筹 ,但是当我写了个 demo,看到站点效果以后,一言难尽:

👍🏻 哥们你真行,是怎么做到这么丑的设计能有这么多 star 的,我是想破头也没想通为什么不请个 ui。
我这里又扭头去做了个 dumi 的 demo 看看效果

这才像话吧,该有的都有,虽说对比上几乎全面落后于 storybook,但是 ui 能看,而且好歹也是更新了好几年了,应该问题不大......吧?
dumi 入坑
总之先来创建项目吧
sh
# 先找个地方建个空目录。
$ mkdir myapp && cd myapp
# 通过官方工具创建项目,选择你需要的模板
$ npx create-dumi
2025 年了,居然还有需要自己手动建文件夹的脚本,这种操作不应该直接放进对话中吗
创建完毕后,可以简单看下目录,比较中规中矩。

接着直接运行项目,来看一下具体的运行效果。

第一难:名字折行
整体设计还是可以的,就是这左上角的名字只给了这么小的地方,大部分情况都会折行,非常不合理。好在有很多前辈已经想办法解决掉了:
js
// 在 .dumirc.ts 中进行修改
export default defineConfig({
...
styles: [
`.dumi-default-header-left {
width: 260px !important;
}`,
],
});
第二难:nav 异常
随后再仔细看,上方的这里显示的并不是"组件",而是某个具体的组件名。

没关系,我们找一下文档,看看怎么改就行了。
js
// .dumirc.ts
themeConfig: {
name: 'test-component',
nav: [
{ title: '介绍', link: '/guide' },
{ title: '组件', link: '/components/Foo' }, // 注意要写 components 而非 src
],
},

单这一块就找了半天,为什么不能在代码中做成预置项,这样一搜就知道在哪配置。
第三难:写 md 文件时标题跟着变了
简单写了写 md 文件,追加了一个 props,结果组件标题也变成了 props


观察下来是不能使用一级标题,它会自动将最后一个一级标题设为组件标题。将 md 文件中的一级标题全部去除后,它将使用文件夹名作为标题。
所以思路可以是写一个一级标题作为标题,其余则正常写 md,如:

第四难:使用 tailwindcss
部分同学已经注意到了,上述代码中使用了 tailwindcss,但 dumi 里基本没说怎么接入,唯一找到的 issue 提问还是过时的,只能手动摸索。在这里贴一个我的方案:
- 安装 tailwindcss
sh
pnpm install tailwindcss @tailwindcss/cli
- 创建 src/input.css 并写入
js
@import "tailwindcss";
- 在入口处 (src/index.ts) 引入 output.css
arduino
import './output.css';
- 启动 tailwind 编译(会自动将代码中的 className 扫描出来并生成对应类加入 output 中)
这里可以选择不同方案:
- npx @tailwindcss/cli -i ./src/input.css -o ./src/output.css --watch 热更新实时编译,但需要你另开一个终端来跑
- 手动跑 npx @tailwindcss/cli -i ./src/input.css -o ./src/output.css,也就是一次性方案
这里我用的是后者,因为我的组件基本是写好了才放过来,比较稳定,只是用于展示给同事,所以不太需要热更新。
不过这个命令太长,所以我在 package.json
中加了个 tailwind
命令。
json
"scripts": {
...
"tailwind": "npx @tailwindcss/cli -i ./src/input.css -o ./src/output.css"
},
这样我只需要 每次更新完组件后跑一下 npm run tailwind 即可。
第五难:发布 npm
在登录 npm 前,你需要确定自己的 npm 源,很多时候都被切成了阿里源,记得要换原始源才行:
js
// 切为 npm 源
npm config set registry https://registry.npmjs.org/
// 切为阿里源
npm config set registry https://registry.npmmirror.com/
接着就是比较正常的几步了:
js
// 登录
npm login
// 发布
npm publish
请注意,包名不能起的太简单,否则很可能跟已有包名重复而报错,所以可以考虑使用 @user/...
的组合来命名,如 @imoo/components
。
这样一来,就跑通了整体流程,至于其他的组件则可以慢慢发布。