React设置type:module转ESM报Module Not Found错误如何解决
问题原因
在package.json中添加"type": "module"配置后,webpack 5 会对ESM模块默认启用完全指定导入路径的严格解析规则,此时你在配置中看到的extensions自动补全扩展名逻辑会被跳过——ESM原生规范要求导入路径必须携带完整文件扩展名,webpack默认遵循这个规则,不会自动为你补.js/.jsx后缀,哪怕extensions列表里已经配置了对应后缀,依然会抛出模块找不到的错误。
不改源码的修复方案
以下方案都不需要修改src目录下的任何import导入语句,按需选择即可:
- 方案1:使用CRACO覆盖配置(最推荐,无需eject、不会修改node_modules文件,配置可持久化)
- 安装开发依赖:
npm install @craco/craco --save-dev - 在项目根目录新建
craco.config.js文件,写入如下配置:module.exports = { webpack: { configure: (config) => { // 关闭ESM严格路径校验,恢复扩展名自动补全逻辑 config.module.rules.forEach(rule => { if (rule.resolve) { rule.resolve.fullySpecified = false } }) return config } } } - 修改
package.json中的scripts字段,将react-scripts命令替换为craco:"scripts": { "start": "craco start", "build": "craco build", "test": "craco test", // 其余脚本保持不变 } - 重启开发服务即可恢复正常。
- 安装开发依赖:
- 方案2:已eject项目直接修改本地webpack配置
如果你之前执行过npm run eject把webpack配置导出到了项目本地,直接打开项目下config/webpack.config.js文件,找到处理.js/.jsx文件的规则段,添加resolve: { fullySpecified: false }配置即可:
修改完成后重启服务生效。{ test: /\.(js|mjs|jsx|ts|tsx)$/, // 保留原有loader、include等所有配置不变 resolve: { fullySpecified: false // 新增这行关闭严格校验 } } - 方案3:临时修改node_modules内配置(仅适合快速验证,重装依赖会失效)
如果不想新增依赖、也不想eject,可以直接打开node_modules/react-scripts/config/webpack.config.js,按照方案2的逻辑给对应js规则加上fullySpecified: false配置,重启服务即可临时解决问题。
注意:不要试图通过修改
extensions配置解决问题,fullySpecified规则优先级高于扩展名自动补全逻辑,只要该规则为true,extensions配置就不会对ESM模块生效。
内容的提问来源于stack exchange,提问作者The KNVB
相关产品推荐
相关产品推荐

