Vite迁移React项目后生产环境报require is not defined错误
解决Vite生产部署时"require is not defined"错误
问题原因
Vite默认遵循ES模块规范,而Webpack兼容CommonJS规范。你的项目开发、构建阶段正常,但部署后报错,说明代码或第三方依赖中存在未被转译的CommonJS语法(require),浏览器原生不支持该语法。
解决方案
1. 清理项目代码中的require语句
检查所有源码文件,将require替换为ES模块语法:
- 静态资源导入:把
const img = require('./assets/logo.png')改为import img from './assets/logo.png' - 动态导入:把
require('./components/Modal')改为import('./components/Modal')(返回Promise,支持异步加载)
2. 添加Rollup CommonJS转译插件
安装@rollup/plugin-commonjs处理第三方依赖中的CommonJS语法:
npm install @rollup/plugin-commonjs --save-dev
在vite.config.js中导入并添加到插件列表:
import commonjs from '@rollup/plugin-commonjs'; // 新增导入
在plugins数组最前面加入:
plugins: [ commonjs(), // 新增,放在react相关插件之前 // ... 原有插件 ],
3. 优化依赖预构建
将使用CommonJS的第三方依赖添加到optimizeDeps.include,让Vite预构建时将其转为ES模块:
optimizeDeps: { include: [ 'process', 'buffer', 'stream-browserify', 'browserify-zlib', 'timers-browserify', // 这里添加你的依赖包名,比如 lodash、axios 等(如果它们用了CommonJS) ], // ... 原有配置 },
4. 补充Node.js模块的浏览器兼容
如果依赖用到Node.js核心模块(如path),安装对应兼容包并配置别名:
npm install path-browserify --save-dev
在resolve.alias中添加:
resolve: { alias: { // ... 原有别名 path: 'path-browserify', }, // ... 原有配置 },
修改后的完整vite.config.js示例
import { defineConfig } from 'vite'; import reactRefresh from '@vitejs/plugin-react-refresh'; import svgrPlugin from 'vite-plugin-svgr'; import envCompatible from 'vite-plugin-env-compatible'; import react from '@vitejs/plugin-react'; import path from 'path'; import fs from 'fs/promises'; import commonjs from '@rollup/plugin-commonjs'; export default defineConfig({ build: { outDir: 'build', rollupOptions: { onwarn(warning, warn) { if ( warning.code === 'THIS_IS_UNDEFINED' || warning.code === 'OTHER_SPECIFIC_WARNING_CODE' ) { return; } warn(warning); }, }, }, css: { modules: { scopeBehaviour: 'local', }, }, plugins: [ commonjs(), reactRefresh(), envCompatible(), svgrPlugin({ svgrOptions: { icon: true, }, }), react({ jsxRuntime: 'automatic', include: [/\.jsx?$/], }), ], resolve: { alias: { Actions: path.resolve(__dirname, 'src/actions/'), Components: path.resolve(__dirname, 'src/components/'), Assets: path.resolve(__dirname, 'src/assets/'), Util: path.resolve(__dirname, 'src/util/'), Routes: path.resolve(__dirname, 'src/routes/'), Constants: path.resolve(__dirname, 'src/constants/'), Helpers: path.resolve(__dirname, 'src/helpers/'), Api: path.resolve(__dirname, 'src/api/'), process: 'process/browser', stream: 'stream-browserify', zlib: 'browserify-zlib', buffer: 'buffer', path: 'path-browserify', }, fallback: { fs: false, crypto: false, }, extensions: ['.js', '.jsx'], }, esbuild: { loader: 'jsx', include: /src\/.*\.jsx?$/, exclude: [], }, optimizeDeps: { include: [ 'process', 'buffer', 'stream-browserify', 'browserify-zlib', 'timers-browserify', ], esbuildOptions: { plugins: [ { name: 'load-js-files-as-jsx', setup(build) { build.onLoad({ filter: /src\/.*\.js$/ }, async (args) => ({ loader: 'jsx', contents: await fs.readFile(args.path, 'utf8'), })); }, }, ], }, }, define: { 'process.env': {}, process: { env: {}, }, }, });
内容的提问来源于stack exchange,提问作者Sampath
相关产品推荐
相关产品推荐

