首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ES模块脚本的CommonJS包装器

ES模块脚本的CommonJS包装器
EN

Stack Overflow用户
提问于 2020-05-27 00:44:00
回答 1查看 1.4K关注 0票数 2

关于ECMAScript模块的节点文档为向用户提供CommonJS脚本和ES模块脚本的“双包”提供了建议。

具体来说,他们建议将ES模块脚本转到CommonJS,然后使用"ES模块包装器“,这是一个ES模块脚本,从CJS导入并将其命名为exports的CJS重新导出为ESM命名的导出。

代码语言:javascript
复制
// ./node_modules/pkg/wrapper.mjs
import cjsModule from './index.cjs';
export const name = cjsModule.name;

我的问题是:是否有可能以相反的方式提供ES模块格式的脚本,但在CommonJS中添加一个简单的包装文件,允许CJS用户对其进行require

就我而言,我看不出有什么方法可以在同步代码中做到这一点。在我看来,CommonJS脚本只能通过异步动态import()导入ES模块。

代码语言:javascript
复制
(async () => {
    const {foo} = await import('./foo.mjs');
})();

但这意味着我的CJS脚本不能导出任何依赖于foo的内容。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-11 01:30:08

无法同步导入ESM模块。 CJS导出是同步的,但ESM导入本质上是异步的。

require() 中, 是同步的;不返回承诺或调用回调。require()从磁盘(甚至网络)读取,然后立即运行脚本,脚本本身可能会产生I/O或其他副作用,然后返回在module.exports上设置的任何值。 在ESM中,模块加载器运行在异步阶段,在第一阶段解析脚本以检测导入和导出的调用,而不运行导入的脚本。在解析阶段,ESM加载程序可以立即检测到命名导入中的错误并抛出异常,而无需实际运行依赖代码。 ESM模块加载器然后异步下载和解析您导入的任何脚本,然后构建一个依赖关系的“模块图”,直到最终找到一个不导入任何内容的脚本。最后,允许执行该脚本,然后允许运行依赖该脚本的脚本,依此类推。

在所有情况下,都不一定能够将ESM转换到CJS。例如,ESM可以使用顶级等待,而CJS模块不能。因此,无法将这些ESM代码转换为CJS:

代码语言:javascript
复制
export const foo = await fetch('./data.json');

CJS和ESM是完全不同的动物。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62033701

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档