javascript - NodeJS计划支持导入/导出es6(es2015)模块

标签 javascript node.js module ecmascript-6 es6-modules

我一直在互联网上寻找有关此问题的明确答案。

当前,NodeJS仅使用CommonJS语法来加载模块,如果您确实要使用标准ES2015模块语法,则必须事先对其进行转换,或者在运行时使用外部模块加载器。

目前,我不太愿意使用这两种方法,NodeJS维护人员是否计划支持ES2015模块?
我完全没有发现任何提示。

目前,NodeJS 6.x声称支持96%的ES2015功能,但没有任何对模块(NodeJS ES2105 support link)的引用。

您是否知道在不久的将来NodeJS是否将立即支持这些模块?

最佳答案

节点13.2.0及以上

NodeJS 13.2.0现在支持不带标志的ES模块🎉但是,该实现仍被标记为实验性的,因此在生产中使用时应谨慎。

要在13.2.0中启用ESM支持,请将以下内容添加到您的package.json中:

{
  "type": "module"
}


所有.js.mjs(或不带扩展名的文件)将被视为ESM。

除了整个package.json选择加入之外,还有许多其他选项,所有选项均在Documentation for 13.2.0中进行了详细说明。

节点13.1.0及以下

那些仍在使用旧版本Node的用户可能想尝试esm模块加载器,它是NodeJS ES模块规范的生产就绪型实现:

node -r esm main.js


详细更新...

2019年4月23日

最近登陆的PR更改了检测ES模块的方式:
https://github.com/nodejs/node/pull/26745

它仍然位于--experimental-modules标志后面,但是模块的加载方式发生了重大变化:


package.type可以是modulecommonjs


type: "commonjs"
.js被解析为commonjs
不带扩展名的入口点的默认值为commonjs
type: "module":
.js被解析为esm
默认不支持加载JSON或本机模块
不带扩展名的入口点的默认值为esm

--type=[mode]允许您在入口点上设置类型。将覆盖package.type作为入口点。
新的文件扩展名.cjs


这专门用于支持以module模式导入commonjs。
这仅在esm加载程序中,commonjs加载程序保持不变,但是如果您使用完整的文件路径,则扩展名将在旧的加载程序中工作。

--es-module-specifier-resolution=[type]


选项是explicit(默认)和node
默认情况下,我们的加载程序不允许导入中的可选扩展名,如果存在一个扩展名,则模块路径必须包含扩展名
默认情况下,我们的加载器不允许导入具有索引文件的目录
开发人员可以使用--es-module-specifier-resolution=node启用commonjs说明符解析算法
这不是“功能”,而是实验的一种实现。预期在删除标志之前会发生变化

--experimental-json-loader


"type": "module"时导入json的唯一方法
启用时,所有import 'thing.json'都将通过实验加载程序,而与模式无关
根据whatwg/html#4315

您可以使用package.main设置模块的入口点


main中使用的文件扩展名将根据模块的类型进行解析



2019年1月17日

Node 11.6.0仍在标志后面列出ES模块为实验模块。

2017年9月13日

NodeJS 8.5.0已发布,并在标志后面支持mjs文件:

node --experimental-modules index.mjs


计划是删除v10.0 LTS版本的标志。

-过时的信息。出于历史目的保留在这里

2017年9月8日

NodeJS master分支已更新,最初支持ESM模块:
https://github.com/nodejs/node/commit/c8a389e19f172edbada83f59944cad7cc802d9d5

它应该在最新的每晚可用(可以是installed via nvm,与现有安装一起运行):
https://nodejs.org/download/nightly/

并在--experimental-modules标志后面启用:

package.json

{
  "name": "testing-mjs",
  "version": "1.0.0",
  "description": "",
  "main": "index.mjs" <-- Set this to be an mjs file
}


然后运行:

node --experimental-modules .


2017年2月:

https://medium.com/@jasnell/an-update-on-es6-modules-in-node-js-42c958b890c#.6ye7mtn37

NodeJS伙计们认为最糟糕的解决方案是使用.mjs文件扩展名。得出的结论是:


  换句话说,给定两个文件foo.jsbar.mjs,使用import * from 'foo'foo.js视为CommonJS,而import * from 'bar'
  会将bar.mjs视为ES6模块


至于时间表...


  在目前的时间点上,
  ES6上需要发生的规范和实现问题
  和虚拟机方面的事情,甚至可以在Node.js开始之前
  设计可支持的ES6模块实施。上班了
  进步,但需要一些时间—我们目前正在寻找
  至少一年左右。


2016年10月:

Node.JS的开发人员之一最近参加了TC-39会议,并撰写了一篇关于实现Node.JS的阻止程序的绝妙文章:

https://hackernoon.com/node-js-tc-39-and-modules-a1118aecf95e

基本的收获是:


对ES模块进行静态分析,对CommonJS进行评估
CommonJS模块允许猴子补丁导出,而ES模块目前不支持
如果没有某种形式的用户输入,很难检测出什么是ES模块以及什么是CommonJS,但是他们正在尝试。
*.mjs似乎是最可能的解决方案,除非他们可以在无需用户输入的情况下准确检测出ES模块


-原始答案-

这已经很长一段时间了。最重要的是,是的,Node最终将支持导入/导出模块的ES2015语法-最有可能在spec for loading modules完成并达成共识后使用。

这是使NodeJS正常运行的原因的a good overview。本质上,他们需要确保新规范适用于主要是有条件的,同步加载的Node以及主要是异步的HTML。

目前尚无人知道,但我想Node会支持import/export进行静态加载,此外还支持新的System.import用于动态加载-同时仍保留require来保留旧代码。

以下是一些有关Node如何实现此目标的建议:


In defense of .js
.mjs modules

关于javascript - NodeJS计划支持导入/导出es6(es2015)模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56132881/

相关文章:

javascript - React.js 节流 mousemove 事件不断抛出 event.persist() 错误

javascript - 在 Node.js 中使用 .toLocaleString()

node.js - Sequelize - 如何使用几何值为数据库播种?

module - 为什么在模块中声明常量时 omp 函数不起作用?

javascript - React Dist 无需服务器、 Node 或 Http 服务器

javascript - 我可以将 Canvas 图像居中吗

python - 当类也在不同的模块中时从另一个模块访问对象?

module - 使用 CasperJS 进行 Web 抓取会返回未记录的奇怪错误

javascript - 使用 JavaScript 获取任何工作日的数值/整数值

javascript - 无法让 populate() 填充 Mongoose 中的数组