使用 Vite 從零開始構建 React 組件庫

這篇文章會介紹一個 React 組件庫項目的搭建、打包、發佈

但不會涉及組件庫文檔站點的構建,如有需要,建議查看《使用 dumi 打包 React 組件庫並生成文檔站點》

另外,雖然本文介紹的是 React 組件庫,但對於 Vue 組件庫也是通用的

 

 

一、創建項目

首先參考 Vite 的文檔創建一個項目

yarn create vite my-packages --template react-ts

// 這裏的 my-packages 是項目名稱,按需修改

生成的項目如下:

結構很簡單,但對於一個組件庫來說,還需要完善

首先是 package.json, 需要將 dependencies 中的基礎庫移到 peerDependencies 和 devDependencies 中:

"dependencies": {
  "classnames": "^2.3.1"
},
"peerDependencies": {
  "react": "^18.2.0",
  "react-dom": "^18.2.0"
},
"devDependencies": {
  "react": "^18.2.0",
  "react-dom": "^18.2.0"
}

// react 版本根據實際需求做調整

這樣就不會把 react 打包到組件庫裏面

然後我們還可以引入 ESLint、Husky 等工具來統一規範

除此之外,我認爲有必要創建兩個目錄:

一個演示頁面目錄 example,用於在開發過程中查看效果

一個管理源碼的目錄 packages,用於打包發佈

 

 

二、組件開發

初始化的項目中有一個 src 目錄,可以先重命名爲 example,用作開發過程中的調試頁面

Vite 項目開發環境入口文件是根目錄下的 index.html,其默認引入的是 /src/main.tsx  文件

現在由於演示頁面的目錄已經改爲 example,所以這裏也需要調整:

<script type="module" src="/example/main.tsx"></script>

 

然後新建一個 packages 目錄,用於管理組件源碼

對於大部分的組件,都會有這三部分:組件 Component、組件創建的 TS 類型 types、組件樣式 styles

以一個簡單的 Button 組件爲例:

在開發的時候,可以直接在 Button.tsx 完成 Component 和 types

然後在 index.tsx 中統一導出

// packages/Button/index.tsx
import Button from './Button';
export type { ButtonProps } from './Button';
export default Button;
import './styles/index.less';

// 這裏同時引入了 styles

然後在 packages/index.ts 中引入並統一導出:

// packages/index.ts
export { default as Button } from './Button';
export type { ButtonProps } from './Button';

這樣就能在使用組件庫的時候,從組件庫的入口文件同時拿到 Component 和 types:

import { Button } from 'my-packages';
import type { ButtonProps } from 'my-packages';

上面是在組件中直接引入了相應的 styles,也可以在最外層統一引入

但最終打包的時候(默認配置)都會整合到一個 style.css 中

 

 

三、組件打包

Vite 提供了一個庫模式用於打包組件庫,直接在 vite.config.ts 中配置即可

// vite.config.ts
import path from 'path';
import { defineConfig } from 'vite';

function resolve(str: string) {
  return path.resolve(__dirname, str);
}

export default defineConfig({
  build: {
    // 打包輸出的目錄
    outDir: 'lib',
    // 防止 vite 將 rgba() 顏色轉化爲 #RGBA 十六進制
    cssTarget: 'chrome61',
    lib: {
      // 組件庫源碼的入口文件
      entry: resolve('packages/index.ts'),
      // 組件庫名稱
      name: 'MyPackages',
      // 文件名稱, 打包結果舉例: my-packages.umd.cjs
      fileName: 'my-packages',
    },
    rollupOptions: {
      // 確保外部化處理那些你不想打包進庫的依賴
      external: ['react', 'react-dom'],
      output: {
        // 在 UMD 構建模式下爲這些外部化的依賴提供一個全局變量
        globals: {
          react: 'react',
          'react-dom': 'react-dom',
        },
      },
    },
  }
})

// 如果引入 'path' 的時候報錯,檢查一下是否安裝了 @types/node

以上 build 配置算是一個最小配置,可以參考官網的《構建選項》查看完整配置


vite 的生產構建使用的是 rollup,以目前的配置只會構建出 js 代碼,對於 typescript 類型,需要藉助 rollup 的 typescript 插件來實現

yarn add @rollup/plugin-typescript -D

然後在 vite.config.ts 中使用插件

import { defineConfig } from 'vite';
import path from 'path';
import react from '@vitejs/plugin-react';
import typescript from '@rollup/plugin-typescript';

function resolve(str: string) {
  return path.resolve(__dirname, str);
}

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    typescript({
      target: 'es5',
      rootDir: resolve('packages/'),
      declaration: true,
      declarationDir: resolve('lib'),
      exclude: resolve('node_modules/**'),
      allowSyntheticDefaultImports: true,
    }),
  ],
  build: {
    // ...
  },
});

打包配置到這裏就完成了,執行 yarn build 命令就能打包組件庫

 

  

四、發佈到 npm

作爲一個組件庫,在發佈到 npm 之前需要調整一下 package.json

{
  "name": "my-packages",
  "version": "0.1.0",
  "type": "module",
  "files": [
    "lib"
  ],
  "main": "./lib/my-packages.umd.cjs",
  "module": "./lib/my-packages.js",
  "typings": "./lib/index.d.ts",
  "exports": {
    ".": {
      "import": "./lib/my-packages.js",
      "require": "./lib/my-packages.umd.cjs"
    }
  }
}

上面設置了 files 字段,其作用和 .npmignore 文件類似

只是 files 是規定哪些文件/目錄會放在包內上傳到 npm,而 .npmignore 是排除不需要上傳的文件

如果需要上傳到私有庫,可以在 package.json 中定義:

{
  "publishConfig": {
    "registry": "https://your.npm.private.com"
  }
}

然後登錄 npm 賬戶,直接發佈即可

npm login

npm version patch

npm publish

 


 

項目地址:https://github.com/wisewrong/bolg-demo-app/tree/main/vite-react-packages

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章