React+Webpack5项目用ES Modules出现import语法报错如何解决?
问题根因
你遇到的两个矛盾报错本质是Node v14的ESM支持特性+Webpack配置文件模块类型匹配问题导致的:
- 第一个
ERR_REQUIRE_ESM报错是因为你项目里装的某个依赖是纯ESM包,只能用import加载,而你一开始webpack配置用CommonJS的require去引入就触发报错 - 第二个
Cannot use import statement outside a module是因为你虽然改了import语法,但Node14默认把.js文件当CommonJS处理,你要么给package.json加"type": "module",要么把配置文件后缀改成.mjs,否则不会识别import语法 - 改cjs之后出现的Segmentation Fault不是Webpack ESM支持的问题,Webpack5对ESM的支持早已稳定,问题是Node14的ESM兼容性缺陷+语法混写:你把配置改成.cjs之后就必须全用CommonJS语法,不能混写export,把module.exports改成export相当于在CommonJS文件里写ESM语法,直接触发Node底层解析崩溃。
正确配置步骤
1. 兼容方案(最稳定,适配React16 + Node14组合)
- 删掉package.json里的
"type": "module"配置,所有工程配置文件用CommonJS语法编写,遇到纯ESM依赖时用动态import加载 - 把所有webpack配置文件后缀改回.js,全用
require()+module.exports语法,对于仅支持ESM的第三方包,不要用顶部require,改成在配置里用异步导入:
module.exports = async () => { const CssMinimizerPlugin = (await import('css-minimizer-webpack-plugin')).default; // 其他ESM依赖同理导入 return { // 你的原有webpack配置内容 } }
2. 全ESM配置方案(适合可接受小版本兼容调整的场景)
- 保留package.json里的
"type": "module"配置 - 所有webpack配置文件后缀改成
.mjs,全用import+export default语法,不要混写require - 注意Node14里加载CommonJS模块时ESM导入只能拿default导出,部分CommonJS编写的loader要写成
import xxx from 'xxx-loader',不要用解构导入
3. React/React-Dom的ESM适配调整
React v16.13.1本身同时支持CommonJS和ESM引入,不需要修改源码,只需要在webpack配置里加别名指定ESM入口即可:
// ESM配置写法示例 export default { resolve: { alias: { 'react$': 'react/esm/react.development.js', // 生产环境换react.production.min.js 'react-dom$': 'react-dom/esm/react-dom.development.js' } } }
业务代码里直接用import React from 'react'即可,不需要额外调整。
注意事项
- Node v14已经停止维护,存在大量ESM兼容Bug,如果条件允许升级到Node v16+,可以避免90%的这类模块解析问题
- 不要在同一个文件里混写CommonJS和ESM语法,要么全用require+module.exports,要么全用import+export,混写必然触发解析错误
内容的提问来源于stack exchange,提问作者Swayam Mohanty
相关产品推荐
相关产品推荐

