react 项目打包单个组件导出为umd踩坑

1,842 阅读2分钟

一、react + ts + antd + vite

1、组件开发好后,在vite.config.ts配置文件中进行如下配置

```
plugins: [
  process.env.NODE_ENV === 'development' && react(), // 打包时import.meta.env.NODE_ENV:production
],
build: {
  ……
  lib: {
    entry: resolve(__dirname, 'lib/main.tsx'), // 打包入口
    name: 'test', 
    fileName: 'test',
    formats: ['umd'], // 打包为通用模块
  },
  rollupOptions: {
    // 确保外部化处理那些你不想打包进库的依赖
    external: ['react', 'react-dom'],
    output: {
      // 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量
      globals: {
        react: 'React',
        'react-dom': 'react-dom',
      }
    },
  }
  ……
}

2、打包后,在本地测试页面引入打包好的umd文件,报错process is not defined, 读不到环境变量,通过搜索发现是要在vite.config.ts中配置define属性

// 定义常量全局替换
define: {
  'process.env': {} 或者 'process.env': process.env
}
```

但是这样配置对我无用,依然报错,报错NODE_ENV is not defined, 然后更改为如下:

// 定义常量全局替换
define: {
  'process.env.NODE_ENV': process.env.NODE_ENV
}`

然后报错production is not defined, 打包时process.env.NODE_ENV="production",分析这里将production解析成了一个变量,于是修改为

// 定义常量全局替换
define: {
  'process.env.NODE_ENV': '"production"',
}`

但是要注意,这样的话本地环境变量也被改成了production, 这样本地run会报错,然后重新修改

const nodeEnv = process.env.NODE_ENV === 'production' ? '"production"' : '"development"';
// 定义常量全局替换
define: {
  'process.env.NODE_ENV': nodeEnv,
}`

至此,测试umd页面中不再报环境变量错误,但报了Cannot read properties of undefined (reading 'Select'),看样子是ant有问题,然后排查配置文件中,有将ant排除打包的配置,

// 将下面的antd 去掉,将antd也打包进去即可,若是引入方安装了antd,则可不打包antd
external: ["react", "react-dom", "antd"],
output: {
  globals: {
    react: "react",
    antd: "antd",
    "react-dom": "react-dom",
  },
},

二、react + ts + antd + webpack

使用webpack打包时,配置如下

const name = 'test';
moduls.exports = {
  entry: { [name]: "./lib/main.tsx" }, // 打包入口
  output: {
    path: distDir,
    filename: "[name].js",
    // 采用通用模块定义
    libraryTarget: "umd",
    library: name,
    // 每一次打包清除上一次打包内容
    clean: true,
  },
  ……
}

也会报错process is not defined,增加如下插件配置

plugins: [
  new webpack.DefinePlugin({ // webpack自带该插件,无需单独安装
    'process.env' : {
      NODE_ENV: process.env.NODE_ENV // 将属性转化为全局变量,让代码中可以正常访问
    }
  }),
  ……
],

然后在打包出来的内容是一个ES Module, 经过搜索和查看官方文档发现要在output中增加一个属性

// 若要使用ES6的exportexport default导出,需配合wenpack的output.libraryExport属性
libraryExport: "default",

同样在externals中按需排除antd, 本地测试需要注释掉antd

externals: {
  "react": "React",
  "react-dom": "ReactDOM",
  // "antd": "antd",
},

至此打包成功,本地测试引用成功