使用 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 轉碼,版權歸原作者所有。