Vite中Rollup打包React同时包含开发生产版本该如何解决
Vite 2.x 生产构建打包React开发版依赖问题修复
问题背景
- 项目基于React搭建,构建工具使用Vite
^2.8.6,Vite生产构建底层依赖Rollup完成模块打包 - 故障表现:生产构建产物中同时存在
react.development.js、react-dom.development.js开发版文件与对应生产版文件,累计产生约1MB无效死代码 - 已尝试操作:在
rollupOptions中配置rollup-plugin-replace,将代码内process.env.NODE_ENV替换为production,未解决问题 - 故障配置片段:
rollupOptions: { plugins: [ rollupPluginReplace({ 'process.env.NODE_ENV': JSON.stringify('production') }), rollupPluginCommonjs(), terser(), visualizer() ], },
- 验证依据:通过rollup-visualizer分析构建产物,确认两类环境的React依赖均被打入最终包,不符合生产构建仅保留生产版依赖的预期。

故障根因
手动注入的Rollup插件打乱了Vite内置的插件执行顺序,且存在重复实现内置能力的问题:
- Vite本身已经内置了生产环境下
process.env.NODE_ENV的替换逻辑,手动额外添加rollup-plugin-replace不会提升替换效果,反而可能因为插件执行优先级问题,错过CJS模块静态分析的关键阶段 - React的CommonJS分发包采用分支判断动态引入不同环境的入口文件,CJS转ESM的静态分析阶段如果没有完成环境变量替换,打包器会将两个分支的依赖全部引入,后续的变量替换和压缩只能删除分支内的代码,无法移除已经被静态分析识别为依赖的开发版文件
- Vite已经内置了CommonJS模块转换、生产环境压缩的能力,手动重复挂载
rollup-plugin-commonjs、terser插件会绕过Vite的依赖预构建流程,直接导致模块解析逻辑异常。
修复步骤
- 删除
rollupOptions.plugins中手动添加的rollupPluginReplace、rollupPluginCommonjs、terser三个插件,不要重复实现Vite内置能力 - 确保项目已安装并启用官方React插件
@vitejs/plugin-react,该插件会自动处理React生产环境的入口映射、JSX编译等逻辑,无需额外手动配置 - 全局检查代码中的React相关导入,删除所有显式指向开发版入口的写法(例如
import React from 'react/cjs/react.development.js'),所有React相关导入统一使用标准写法import React from 'react' - 调整后的vite配置参考:
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import { visualizer } from 'rollup-plugin-visualizer' export default defineConfig({ plugins: [react()], build: { // 直接使用Vite内置的terser压缩配置即可,无需手动引入terser插件 minify: 'terser', rollupOptions: { plugins: [visualizer()] } } })
- 执行生产构建时直接运行
vite build命令,不要携带--mode development参数,默认构建模式会自动将环境变量设置为production,完成React生产依赖的Tree Shaking,彻底移除开发版冗余代码。
验证方式:构建完成后重新查看rollup-visualizer的分析结果,产物中只会保留
react.production.min.js与react-dom.production.min.js,开发版文件会被完全移除,产物体积会下降约1MB。
内容的提问来源于stack exchange,提问作者Ihsan Fajar Ramadhan
相关产品推荐
相关产品推荐

