当前位置:首页 > 科技  > 软件

一个提出五年的 Node.js 模块问题,终被解决!

来源: 责编: 时间:2024-03-26 17:40:02 111观看
导读一直以来 Node.js 中存在一个问题,CommonJS 与 ES Modules 如何更好的共存? 是令大多数 Node.js 开发者头疼的问题。问题当在 ES Modules 模块中引入 CommonJS 模块代码,一切是 Ok 的。如下代码所示:// c.jsmodule.export

一直以来 Node.js 中存在一个问题,CommonJS 与 ES Modules 如何更好的共存? 是令大多数 Node.js 开发者头疼的问题。6MK28资讯网——每日最新资讯28at.com

问题

当在 ES Modules 模块中引入 CommonJS 模块代码,一切是 Ok 的。如下代码所示:6MK28资讯网——每日最新资讯28at.com

// c.jsmodule.exports = {  moduleName: 'a'}
// m.mjsimport C_Module from './c.js'console.log(C_Module); // { moduleName: 'a' }

换一种方式,让 CommonJS 引入 ES Modules,如下代码所示:6MK28资讯网——每日最新资讯28at.com

// m.mjsexport default 'm'
// c.jsconst M_Module = require('./m.mjs')console.log(M_Module);

终端运行 node c.js,会得到如下提示6MK28资讯网——每日最新资讯28at.com

图片图片6MK28资讯网——每日最新资讯28at.com

ERR_REQUIRE_ESM 这个错误太熟悉不过了,它困惑了很多的 Node.js 开发者,为什么换个顺序就不行?6MK28资讯网——每日最新资讯28at.com

看到的很多答案是这样的 “不支持使用 require 加载 ES 模块,因为 ES 模块是异步执行的”,后面大家就默认了 “CommonJS 是同步,ES Modules 是异步” 这样的一个规则。6MK28资讯网——每日最新资讯28at.com

2019 提出后很遗憾未能继续推进

CommonJS 模块如何加载 ES Modules 模块,这个问题 2019 年就已经提出,参考 “Support requiring .mjs files” https://github.com/nodejs/node/pull/30891 这个问题在当时没有被解决。6MK28资讯网——每日最新资讯28at.com

图片图片6MK28资讯网——每日最新资讯28at.com

ES Modules 在文件顶层可以使用 Top-Level Await,该方法看之前的介绍,是在使用 esm 加载器加载的 .mjs 文件上使用 require 的功能时,使用了与 esm Top-Level Await 相同的权衡。6MK28资讯网——每日最新资讯28at.com

这意味着:如果可能,所有执行和评估都是同步进行的,通过立即展开执行的组件承诺。这意味着任何现有的代码都不应该有可观察到的行为变化,因为到目前为止还不存在任何异步模块。问题在于,一旦使用需要异步执行的模块,它必须让出事件循环来执行该操作,这反过来又允许其他代码在异步操作之后的继续执行之前执行,这对于现在变成了异步模块的调用者是可观察到的。如果这对你的调用者很重要,那么意味着将你的模块执行异步化可能被视为库的破坏性更改,但实际上,对于大多数调用者来说,这并不重要。而且,由于当前的生态系统,零个模块是异步执行的,因此在有异步执行的模块之前,这种方法没有任何缺点,因为没有执行会改变人们今天所期望的(当然,除了不再错误地要求("./foo.mjs"))。6MK28资讯网——每日最新资讯28at.com

最后,问题被关闭了,原因是 “因为纯粹从技术角度来看,目前尝试在事件循环已经运行时旋转它是行不通的”。6MK28资讯网——每日最新资讯28at.com

图片图片6MK28资讯网——每日最新资讯28at.com

问题是挺错综复杂的,感兴趣的可以去看看 2019 年提出的这个 Issue。6MK28资讯网——每日最新资讯28at.com

2024 由 Joyee Cheung's 提出解决方案

2019 ~ 2024 这一令大多数开发者头疼的问题,由 Node.js 的维护者成员 “Joyee Cheung” 再次提出了解决方案。参考 Issue “module: support require()ing synchronous ESM graphs” https://github.com/nodejs/node/pull/519776MK28资讯网——每日最新资讯28at.com

图片图片6MK28资讯网——每日最新资讯28at.com

参考 Joyee Cheung 博客的介绍 https://joyeecheung.github.io/blog/2024/03/18/require-esm-in-node-js/6MK28资讯网——每日最新资讯28at.com

图片图片6MK28资讯网——每日最新资讯28at.com

去年年底左右,Joyee Cheung 发现了 ESM 的求值可以基于语法同步,而只是 Node.js 将异步性扔到加载过程中后,便与 @GeoffreyBooth 开始讨论重新启动同步 require(esm)。6MK28资讯网——每日最新资讯28at.com

因此,才有了这个 PR。与 2019 年的 PR 相比主要区别在于它试图将 require(esm) 的范围保持小型,并且仅支持加载同步 ESM。6MK28资讯网——每日最新资讯28at.com

后续会通过 --experimental-require-module 标志启用,则加载的 ECMAScript 模块 require() 时要满足以下要求:6MK28资讯网——每日最新资讯28at.com

  • 在最接近的 package.json 文件或 .mjs 扩展中明确标记为 ES 模块,具有 "type": "module" 字段
  • 完全同步(不包含 Top-Level Await)

有网友就在下面问了,这能向后移至到 Node.js 18? 大家还是很喜欢这个功能的!Node.js v20 可能还有希望,这要取决于 Node.js 的发布团队,期待下个 Node.js 版本!6MK28资讯网——每日最新资讯28at.com

图片图片6MK28资讯网——每日最新资讯28at.com

这一问题的解决对 Node.js 模块来讲是里程碑式的,很敬佩 Joyee Cheung 的才华!6MK28资讯网——每日最新资讯28at.com

参考

  • https://github.com/nodejs/node/pull/30891
  • https://github.com/nodejs/node/pull/51977
  • https://joyeecheung.github.io/blog/2024/03/18/require-esm-in-node-js/

本文链接:http://www.28at.com/showinfo-26-79450-0.html一个提出五年的 Node.js 模块问题,终被解决!

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 我们一起聊聊如何向文本添加渐变效果和图案

下一篇: 你还在用Mybatis?试试这款神器,纵享丝滑

标签:
  • 热门焦点
Top