如何从零开始写一个react组件库

565 阅读3分钟

今天给大家分享一下我写的组件库Actify,已经开源了,也发布到npm上去了。 是一个基于Google Material Design 3的组件库。

首先是取名字

组件库一开始就要想一个好名字,想好后去npmjs.com搜索一下,看是否有已经存在的名字,也可以去Github上面搜索一下,尽量避免和别的开源项目重名,还有域名也可以去查一下是否可以注册,优先com域名。

因为我写vue的时候比较喜欢使用vuetify这个组件库,所以首先想到的是reactify这个名字,发现已经有npm的库了,于是把前面的re去掉,直接actify,可以用,还更简洁,于是我赶紧npm publish一个上去,先把名字占了。后面就可以愉快的开发组件了。

技术选型

一开始准备使用Next.js来写,发现编译不了库,写文档网站应该可以。后面采用Vite + Ract + Tailwind CSS来写。用一个项目,既维护文档页面,又维护组件库。

目录结构

.
├── .gitignore
├── README.md
├── src
│   └── pages // 文档页面
├── node_modules
├── packages // 库目录
│   └── components // 组件目录
├── vite.config.js // vite配置文件
└── package.json

package.json配置

  • 编译成文档网站
    scripts: {
        "build": "vite build"
    }
    
  • 编译成lib库
    scripts: {
        "build:lib": "vite build --mode lib"
    }
    

vite.config.js配置

  • import @ 基于根目录

    resolve: {
        alias: {
            '@': path.resolve(__dirname, '.')
        }
    }
    
  • 使用vite-plugin-pages配置src/pages作为路由页面

  • defineConfig配置打包模式

    export default defineConfig(({ mode }) => {
      if (mode == 'lib') {
        // build for lib
        return {
          resolve,
          build: {
            outDir: 'lib',
            lib: {
              entry: path.resolve(__dirname, 'packages/components/index.js'),
              name: packageJson.name,
              fileName: packageJson.name
            },
            rollupOptions: {
              external: [...Object.keys(packageJson.peerDependencies)],
              output: {
                globals: {
                  react: 'React'
                }
              }
            }
          }
        }
      }
      return {
        resolve,
        plugins: [react(), pages()]
      }
    })
    

Icon图标

  • 一开始使用了react-icons
  • 后面直接使用Lucide,虽然react-icons包含了lucide图标

组件页面,比如Button

  • 写到 /packages/Button/index.jsx
  • 一开始准备使用clsx,tailwind-merge,class-variance-authority来写组件,后来发现工作量太大
  • 后面直接使用@material/web里面的组件,都是web component,那就二次封装一下,后面可能会慢慢重写
  • 因为web component是shadow-root,里面的样式不好修改,好在里面使用了css变量,我们在外面修改css变量,即可修改web component组件的样式

文档页面,比如Button

  • 写到 /src/pages/buttons/button.jsx
  • 使用prismjs实现代码高亮
  • 后面会采用markdown来重写文档,主要使用react-markdown

组件官网actifyjs.com

  • npm更新发布,采用GitHub Actions自动化发布
  • 使用Vite编译成纯静态,部署在vercel服务器上
  • 需要注意的是Github上面Organization下面的项目是不能免费部署到vercel,个人项目可以

FAQ

  • 为什么不使用ts?我不想把时间浪费在类型标注上面,不能为了用ts而使用ts,最后变成了AnyScript,看发展的情况,不排除转成ts,我想也不是什么难事
  • 已经有element-ui,ant.design,mui,arco.deisgn...,为什么你还要造轮子?其实ui组件库,就像网站的皮肤,人的衣服一样,不同的人有不同的偏好,每一个组件库都有自己的设计语言,设计规范,我只是比较喜欢Material Design,喜欢它的elevation,ripple,focus-ring而已,况且现在它来到第3版M3,相较于之前的M2,有些变动,具体可查看 m3.material.io