轮子系列:使用vite从零开发React组件库

4,051 阅读4分钟

前言

新年第一篇,与团队的小伙伴开启一波造轮子的系列 - 怎么样打造一个组件库

BOTY-DESIGN

首先组件库需要一个响亮的 title -> Boty-Design

BOTY 的全称是 battle of the year(国际顶级街舞团队大赛),总之 cool 就行了

Vite

最近 Vite2 出来了,也支持 react 开发,我们选择 Vite 来作为组件库的开发工具

如上图所示,Vite 开发环境的构建速度比常规的 Webpack 要快很多,这也是为什么我们使用 Vite 来进行组件库开发的主要原因

Vite 原理、源码解析相关博客,可以移步去掘金 Vite 专栏,这里就不过多介绍了

dumi

由于 Vite 并没有非常好用的文档工具,也不是所有的轮子都需要自己造,所以我们选择了 dumi 集成到我们的项目中作为文档工具使用。

dumi 配置

由于我们并没有使用 umi,所以采用官方推荐的第三方使用方法

// 安装模块。
yarn add dumi cross-env -D

// 增加启动命令,修改 package.json。
  "scripts": {
    "dumi": "cross-env APP_ROOT=dumi dumi dev",
    "dumi-build": "cross-env APP_ROOT=dumi dumi build"
  },

// 增加配置,新建 config/config.js。
export default {
  chainWebpack(memo) {
    memo.plugins.delete('copy');
  },
};

新建文档目录 dumi/docs/,这里的 dumi 目录即启动命令的环境变量 APP_ROOT,你可以随意同步修改。

新建文档 dumi/docs/index.md,后续即可根据 dumi 的文档进行正常的 doc 开发了

组件 API 自动生成

dumi 可以通过 JS Doc 注解 + TypeScript 类型定义的方式

interface BaseProps {
  /**
   * @description 自定义样式名
   */
  className?: string;
  /**
   * @description 自定义样式
   */
  style?: React.HTMLProps<HTMLStyleElement>;
}

// dumi.md 使用
<API src="../../src/components/Button/index.tsx"></API>

由于我们这次基本都是用 ts 开发,很轻松可以使用 dumi 的这个功能生成我们想要的 Api,如下图:

dumi github aciton + github page

项目根路径新建 .github/workflows/gh-pages.yml 文件

name: github pages

on:
  push:
    branches:
      - master # default branch

jobs:
  deploy:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v2
      - run: yarn install
      - run: yarn run dumi-build
      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./dumi/dist

后续合并 master 的时候会触发 action 自动构建,github page 选择生成好的静态分支目录即可

可能遇到的问题

  1. config/config.js 不生效

由于你的启动命令已经指定了 APP_ROOT,也就是修改了运行路径,所以把 config 也放在 APP_ROOT 指定路径下

  1. dumi windows 下 build 失败

这个暂时无解,生成静态文件的路径格式在 windows 下不合法,直接在 Linux 或者 mac 上构建是正常的,所以用 gitlab aciton 是可以的

  1. 别名不生效

修改 config/config.js 或者 .umirc.ts

chainWebpack(memo) {
    memo.module
      .rule('js')
      .test(/\.(js|mjs|jsx|ts|tsx)$/)
      .include.add(join(__dirname, '..', '..', 'src/components')).end()
      .exclude.add(/node_modules/).end()
      .use('babel-loader')
  },
  alias: {
    'boty': join(__dirname, '..', '..', 'src/components'),
  },

配置完之后可以正常的 dumi 的 md 文件中使用 alias

仅仅指定 alias 是不行的,必须同时添加新的 rule,指定目录解析

开始启航

前面准备工作做的已经差不多了,马上接下来,就进行一轮造轮子的工程

这里首先致谢 Ant Design 团队,我们的轮子的设计与部分内容都是参考(借鉴)业内专业的 Ant Design

特别是icon 组件,样式与设计太难了,直接引用了 @antd/icons 了

第一个组件 Button

刚开始肯定不能搞个最难的,做不出来那可不就直接劝退了嘛。

所以选择 button 组件来练练手(其实内容也不少 = =!),先分析一下 button 的功能

其实大体就是自定义样式、功能与预设样式、功能。

我们在里面加入了一下贴合业务的功能,比如 loading 存在的时候与 antd 的设计不同,不是由开发者去开启、关闭 loading 的状态,而是直接将 click 方法当做异步函数,点击的时候就开启 loading 状态,等待回调结束会关闭 loading 状态。

同样在后续的组件开发也是如此,除了参考 antd 的设计之外,也会根据一些业务来定制一些功能。

为什么要造轮子

距离上一次我造轮子,大概过去了 5 年,也是根据 VUM1.0 去改造的升级版本,当时的作者言川大佬在 vue2 出来的时候,没有抽得出空来更新 VUM 这个 vue 移动端组件库,而我是 Vue 的初学者,本着更深入学习的想法,就将 VUM 从 vue1 升级到 vue2。虽然那个时候很忙,但是收获还是蛮多也挺开心的。

这一次的轮子也不是从零开发,毕竟我们站在了 AntD 这个巨人的肩膀上,可以看得更远。

在这个项目中,除了技术之外,更多的可能是从设计、产品的角度来打磨这套产品。

同时也希望这个项目能对一些同学有一定的帮助。

写在最后

项目介绍

项目地址

项目预览地址

我们会反复修改一些细节部分,有想追的朋友可以 star 一下

项目成员

  • 清尘 - 负责样式
  • serializedowen - 负责PUA
  • CookieBoty - 负责打杂