likes
comments
collection
share

使用Vite构建cjs和esm格式的React组件库

作者站长头像
站长
· 阅读数 21

背景

React 有很多现成的组件库,例如 Material UI 和 Ant Design 等都可以拿来直接用。为什么还要自己搭建 React 的组件库?

其实我们现实中会出现很多定制化的需求,并不能完全直接使用组件库的组件完成,多或少都会对上面的组件进行修改或者二次封装;这些定制化的需求,可能会应用到现实中的所有相同类型的项目当中,把这部分公共的组件抽离出来就更加有必要了。

使用Vite构建cjs和esm格式的React组件库

思路

实现 TypeScript 类型支持的 React 组件库思路

  1. 将 *.tsx 文件导出并打包成 esm 和 cjs 等结构的 *.js 文件。
  2. 生成 *.d.ts 类型文件,让组件库支持 TypeScript 类型。
  3. *.css 样式文件与 *.tsx 文件分离,有利于实现组件和样式的按需加载。

实现

使用Vite构建cjs和esm格式的React组件库

一. 初始化项目

方法一:

首先,确保您在机器上已经安装了Node.js。然后,在终端中执行以下命令来全局安装Vite:

npm install -g create-vite

接下来,使用Vite初始化一个新的React项目:

create-vite my-component-library --template template-react-ts

方法二(推荐):

# npm 7+, extra double-dash is needed:
npm create vite@latest my-component-library --template template-react-ts

# yarn
yarn create vite my-component-library --template template-react-ts

# pnpm
pnpm create vite my-component-library --template template-react-ts

# Bun
bunx create-vite my-component-library --template template-react-ts

这个命令将会创建一个名为my-component-library的目录,并在其中生成一些初始化的React项目文件。

二、组件开发和导出

进入到my-component-library目录中,您可以开始编写属于您组件库的React组件。

|-- src
    |-- components
        |-- Button.tsx
        |-- Input.tsx
    |-- main.js

例如,您可以在src目录下创建一个Button.tsx文件,编写一个简单的按钮组件:

import React from 'react';

function Button({ text, onClick }) {
  return (
    <button onClick={onClick}>
      {text}
    </button>
  );
}

export default Button;

在这里,我们编写了一个Button组件,并通过export default语句进行导出。

三、配置Vite

配置Vite构建选项 在my-component-library目录下,找到并打开vite.config.js文件。在文件中添加以下配置选项:

// vite.config.js
import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react-swc";
import { resolve, join } from "path";
import { visualizer } from "rollup-plugin-visualizer";

export default defineConfig({
  plugins: [react(), visualizer() as any],
  build: {
    lib: {
      entry: 'src/main.ts', // 组件库的入口文件
      name: 'MyComponentLibrary', // 组件库的全局变量名
      fileName: format => `my-component-library.${format}.js`, // 构建输出的文件名
    },
    rollupOptions: {
      external: ['react', 'react-dom'], // 外部依赖
      output: [
      // ES Module 模块格式的编译
        {
            format: "es",
            entryFileNames: "[name].mjs",
            preserveModules: true,
            exports: undefined,
            dir: resolve(__dirname, `es`),
            preserveModulesRoot: "src",
       },
       // CommonJS 模块格式的编译
       {
            format: "cjs",
            entryFileNames: "[name].js",
            //让打包目录和我们目录对应
            preserveModules: true,
            exports: "named",
            //配置打包根目录
            dir: resolve(__dirname, `lib`),
            preserveModulesRoot: "src",
	},
    ],
    },
  },
});

在上述配置中,我们使用build.lib.entry来指定组件库的入口文件(例如src/main.ts),build.lib.name来指定组件库的全局变量名(例如MyComponentLibrary),build.lib.fileName指定构建输出的文件名,可以根据需要使用不同的格式(例如escjs)。此外,我们还配置了外部依赖(如reactreact-dom)和对应的全局变量名。

四、配置tsconfig.build.json

my-component-library目录下新建一个tsconfig.build.json文件。

// tsconfig.build.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "declaration": true,
    "emitDeclarationOnly": true,
    "outDir": "./es",
    "noEmit": false
  },
  "include": [
    "src"
  ]
}

五、配置package.json

...
"name": "my-component-library",
"version": "1.0.0",
"scripts": {
+ "build": "rimraf es && tsc && vite build && tsc --project tsconfig.build.json",
},
"main": "lib/index.js",
"module": "es/index.mjs",
"typings": "es/index.d.ts",
...

六、构建组件库

完成组件开发和Vite配置后,使用以下命令来构建组件库:

npm run build

Vite将会根据vite.config.js中的配置选项,生成构建输出的文件并保存在eslib目录下。

七、使用组件库

构建完成后,您可以将eslib目录下生成的文件直接用于其他项目中,例如通过npm包管理工具进行安装和引入。

在您的目标项目中,您可以使用import或require语法来导入组件库的组件:

  • ES模块中使用import:
import Button from 'my-component-library/es/index.mjs';
  • CommonJS模块中使用全局引用:
<script src="my-component-library/lib/index.js"></script>

注意:上述示例中的文件路径根据实际构建生成的文件名和文件路径进行调整。

结论

通过使用Vite构建工具,我们可以快速构建React组件库,并实现同时支持cjsES模块化导出。通过适当的配置,我们可以生成适用于不同模块系统的构建文件,并轻松地在其他项目中使用我们的组件库。希望本文对您有所帮助!

Q&A

  • Q: 有源码吗?

当然有,地址如下:github.com/027xiguapi/…,有兴趣的话可以大家一起探讨,同时也欢迎大家forkstar