如何在单个JavaScript文件中同时使用仅ESM规范npm包与普通npm包
解决方案
方案1:使用静态import(优先推荐)
你已经在package.json中配置了"type": "module",Node.js的ESM规范原生支持直接导入CommonJS类型的包,不需要用动态import语法,直接静态导入langs的默认导出即可:
import {franc} from 'franc' // 直接静态导入langs的默认导出 import langs from 'langs' const langCode = franc('Alle menslike wesens word vry') console.log(langCode) console.log(langs.where("3", "kor"));
该方案符合常规开发习惯,无额外异步逻辑,性能最优。
方案2:动态import配合await(按需加载场景使用)
如果你确实需要动态加载langs包,需要使用await等待动态import的Promise执行完成,再取出模块的default属性作为langs实例:
Node.js 14.8及以上版本支持顶层await,可直接编写如下代码:
import {franc} from 'franc' const langsModule = await import('langs') const langs = langsModule.default const langCode = franc('Alle menslike wesens word vry') console.log(langCode) console.log(langs.where("3", "kor"));
如果Node版本不支持顶层await,可把逻辑包裹在自执行async函数中:
import {franc} from 'franc' (async () => { const langsModule = await import('langs') const langs = langsModule.default const langCode = franc('Alle menslike wesens word vry') console.log(langCode) console.log(langs.where("3", "kor")); })()
问题原因说明
- 动态
import()语法的返回值是Promise实例,不是实际的模块内容,直接调用实例上不存在的方法自然会报错 - CommonJS类型的包在ESM规范中导入时,所有导出内容都会被包装到模块对象的
default属性下,所以需要从resolve后的模块对象中取出default属性,才能拿到langs的实际方法集合。
内容的提问来源于stack exchange,提问作者Hardik Sharma
相关产品推荐
相关产品推荐

