Node.js14引入i18next后动态导入ES模块返回空对象问题求助
解决方案
根因说明
你项目配置"type":"module"后,Node会默认将所有.js文件识别为ES Module规范,和你原文件中使用的CommonJS规范的module.exports导出语法不兼容,同时Node 14对CommonJS类型第三方包的ES Module默认导入也存在兼容适配问题,才会出现导入后模块为空的情况。
具体修复方案
- 方案1:全链路统一使用ES Module规范
- 修正
accessLayer.js的导出语法,替换原有module.exports写法:// 如果你原来的导出是默认导出 export default authenticate // 如果是命名导出 export const authenticate = xxx - 修正i18next导入写法,适配Node14对CommonJS包的导入规则:
// 替换原来的默认导入,使用全量导入 import * as i18next from 'i18next'; const {languageTranslate} = i18next; - REPL测试时直接使用
await加载动态导入的模块,读取导出内容:> node --experimental-repl-await > const aa = await import('./app/accessLayer.js') // 默认导出的话调用.default拿到导出对象 > const auth = aa.default() > auth.authenticate('xxxx') // 命名导出的话直接取对应属性 > aa.authenticate('xxxx')
- 修正
- 方案2:保留CommonJS规范,不改动原有导出逻辑
- 可选操作:如果其他文件需要保留ES Module配置,可以单独把
accessLayer.js的后缀改为.cjs,无需修改package.json的"type":"module"配置,该文件会默认被识别为CommonJS规范;如果没有其他ES Module文件,直接去掉package.json中的"type":"module"配置即可 - 把
accessLayer.js中的ES Module导入替换为CommonJS导入:const i18next = require('i18next'); const {languageTranslate} = i18next; - 直接用原来的
require方式加载模块即可正常使用。
- 可选操作:如果其他文件需要保留ES Module配置,可以单独把
内容的提问来源于stack exchange,提问作者Paul Carlson
相关产品推荐
相关产品推荐

