为何Vite/TS会同时打包react-jsx-runtime的生产与开发版本?
解决Vite/Rollup打包时同时包含react-jsx-runtime生产和开发版本的问题
问题描述
tsconfig中配置了"jsx": "react-jsx",使用Vite+Rollup打包组件库时,即使通过cross-env NODE_ENV=production设置生产环境,最终产物里仍同时打包了react-jsx-runtime.production.min.js和react-jsx-runtime.development.js。将react/jsx-runtime设为external会把两者都排除,但这不符合生产打包需要内嵌runtime的需求,需只保留生产环境的runtime代码。
解决方案
核心是让Rollup明确根据生产环境解析React的jsx-runtime,以下两种方式均可实现:
方式一:指定Rollup的resolve条件
在vite.config.ts的rollupOptions中添加resolve.conditions,强制优先选择生产环境的包入口:
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' export default defineConfig({ // 显式声明NODE_ENV,确保环境变量正确传递 define: { 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), }, build: { lib: { entry: './src/index.tsx', formats: ['es'], name: `button`, fileName: `button`, }, rollupOptions: { external: ['react'], resolve: { // 优先读取package.json中标记为production的导出项 conditions: ['production'], }, }, }, plugins: [react()], })
方式二:直接别名映射到生产版本
如果方式一不生效,可通过Rollup的别名机制直接将react/jsx-runtime指向生产环境文件:
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import path from 'path' export default defineConfig({ define: { 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV), }, build: { lib: { entry: './src/index.tsx', formats: ['es'], name: `button`, fileName: `button`, }, rollupOptions: { external: ['react'], plugins: [ { resolveId(id) { if (id === 'react/jsx-runtime') { return path.resolve(__dirname, 'node_modules/react/jsx-runtime.production.min.js') } }, }, ], }, }, plugins: [react()], })
原理说明
React的package.json通过exports字段定义了不同环境的入口,Rollup默认可能读取多个条件下的导出,导致同时打包生产和开发版本。通过指定conditions: ['production']或直接映射生产文件,可让Rollup仅选择生产环境对应的runtime,避免开发版本被打包。
内容的提问来源于stack exchange,提问作者lancerael
相关产品推荐
相关产品推荐

