這篇文章會介紹一個 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