使用 Vite 從零開發 React 組件庫

前言

新年第一篇,與團隊的小夥伴開啓一波造輪子的系列 - 怎麼樣打造一個組件庫

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  這個巨人的肩膀上,可以看得更遠。

在這個項目中,除了技術之外,更多的可能是從設計、產品的角度來打磨這套產品。

同時也希望這個項目能對一些同學有一定的幫助。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。