Node配置React SSR时type:module下模块导入与导出错误如何解决?
问题排查与解决方案
根因说明
你在package.json中配置了"type": "module",启用了Node.js原生ES Module(ESM)规范,该规范有两个强制规则直接触发了你的报错:
- 导入本地相对路径模块必须携带完整文件后缀,不可省略
.js/.json等后缀 - ESM和CommonJS(CJS)模块的导出/导入语法不兼容
问题1:省略后缀触发Cannot find module错误
方案1:全量补充文件后缀
所有本地相对路径的导入语句都补全.js后缀,包括你现有代码中的如下位置:
// 修改前 import Home from './client/src/pages/Home'; import userRoutes from "./routers/user"; import postRoutes from "./routers/post"; import commentsRoutes from "./routers/comment"; import policyRoutes from "./routers/policy"; // 修改后 import Home from './client/src/pages/Home.js'; import userRoutes from "./routers/user.js"; import postRoutes from "./routers/post.js"; import commentsRoutes from "./routers/comment.js"; import policyRoutes from "./routers/policy.js";
方案2:webpack配置自动补全后缀(推荐)
因为你用了webpack打包服务端代码,可以在webpack.server.js中配置自动补全后缀,避免手动修改所有导入语句:
// webpack.server.js 增加如下配置 export default { // 其他原有配置... resolve: { extensions: ['.js', '.jsx', '.json'] } }
问题2:补全后缀后触发does not provide an export named 'default'错误
这个错误是因为你的路由文件(比如./routers/post.js)用的是CommonJS的module.exports = xxx语法导出,和ESM导入语法不兼容,对应解决方法如下:
方案A:修改路由文件为ESM导出语法(推荐)
把所有路由文件的导出语句统一改为ESM规范:
// 路由文件末尾修改为 export default router; // 如果有其他命名导出也对应改为export const xxx = ...
方案B:修改导入语法兼容CJS模块
如果不想修改原有路由文件的导出语法,可以把导入语句改为如下写法:
// 修改前 import postRoutes from "./routers/post.js"; // 修改后 import * as postMod from "./routers/post.js"; const postRoutes = postMod.default;
额外注意事项
- 第三方依赖的导入不需要补全后缀,只有本地相对路径的导入需要处理
- 如果你的React组件文件是
.jsx后缀,记得在webpack的resolve.extensions里加上.jsx,同时确认babel配置能正确转换jsx语法
内容的提问来源于stack exchange,提问作者Egoi Cantero Viqueira
相关产品推荐
相关产品推荐

