Webpack 5+Babel项目切换至ES6模块后开发模式出现Uncaught ReferenceError: require is not defined错误的解决方法
这个坑我之前踩过!核心原因很明确:你开发模式下跳过了node_modules的转译,但很多第三方依赖依旧是用CommonJS(require)语法编写的,而浏览器原生并不支持require,所以才会抛出这个错误。生产环境没问题是因为构建时可能默认处理了这些依赖,或者你生产配置里没有完全排除node_modules的转译。
下面给你几个实用的解决思路,按优先级推荐:
1. 针对性转译有问题的CommonJS依赖
不用全盘转译node_modules(那样会拖慢开发构建速度),只转译那些确实用了require的依赖。修改你的Webpack配置文件,调整module.rules里的排除规则,用负向预查把需要转译的依赖从排除列表中剔除:
module.exports = { // ...其他配置 module: { rules: [ { test: /\.js$/, // 排除node_modules,但保留xxx和yyy这两个需要转译的依赖 exclude: /node_modules\/(?!(xxx|yyy)\/)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } } ] } }
这里的(?!...)是正则的负向预查语法,意思是“除了括号里的依赖之外,其他node_modules内容都排除”。你只需要把实际报错的依赖替换成xxx、yyy即可,这样既能解决问题,又不会过多影响构建速度。
2. 让Webpack优先加载ES模块版本的依赖
很多现代第三方库会在package.json里提供module字段,指向它们的ES模块版本(而非CommonJS)。你可以修改Webpack的resolve配置,让它优先加载这些ES模块文件:
module.exports = { // ...其他配置 resolve: { extensions: ['.mjs', '.js', '.json'], // 先找module字段对应的文件,再找main mainFields: ['module', 'main'] } }
这样Webpack会优先选择ES模块版本的依赖,自然就不会出现require语法了,也不需要额外转译。
3. 检查是否有遗漏的require语句
有时候报错可能不是第三方依赖的问题,而是你自己的代码里漏改了某些require——比如动态加载的场景(require('./components/' + componentName)),这种情况需要改成ES模块的动态导入import('./components/' + componentName),Webpack会自动处理这种语法。
4. 临时方案:开发模式下取消排除node_modules(不推荐)
如果你的项目依赖很少,或者实在找不到具体的问题依赖,可以尝试在开发模式下去掉exclude: /node_modules/这条规则,让Babel转译所有依赖。但请注意,这会显著降低开发构建速度,只适合小型项目临时救急。
内容的提问来源于stack exchange,提问作者user12687104

