Talk is cheap. Show me your code

使用 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

posted @ 2022-09-07 16:55  Wise.Wrong  阅读(4817)  评论(3编辑  收藏  举报