Node.js 计划支持 import/export ES6 (ECMAScript 2015) 模块
Node.js plans to support import/export ES6 (ECMAScript 2015) modules
我在网上找遍了都没有一个明确的答案。
目前 Node.js 仅使用 CommonJS 语法加载模块,如果你真的想使用标准的 ECMAScript 2015 模块语法,你要么必须事先转译它,要么使用外部模块加载器在运行时。
目前我不太愿意使用这两种方法中的任何一种,Node.js 维护者甚至计划支持 ECMAScript 2015 模块吗?我还没有找到任何关于这个的提示。
目前 Node.js 6.x 声称支持 96% 的 ECMAScript 2015 功能,但没有任何模块参考 (Node.js ECMAScript 2015 support link)。
您知道 Node.js 是否会在不久的将来开箱即用地支持这些模块吗?
Node.js 13.2.0 及以上
Node.js 13.2.0 现在支持没有标志的 ES 模块。但是,该实现仍被标记为实验性的,因此在生产中谨慎使用。
要在 13.2.0 中启用 ECMAScript 模块 (ESM) 支持,请将以下内容添加到您的 package.json
:
{
"type": "module"
}
所有 .js
、.mjs
(或没有扩展名的文件)都将被视为 ESM。
除了整个 package.json
opt-in,还有许多不同的选项,所有这些都在 documentation for 13.2.0.
中有详细说明
Node.js 13.1.0 及以下
那些仍在使用旧版本 Node 的人可能想尝试 [esm][3]
模块加载器,它是 Node.js 的 ES 模块规范的 production-ready 实现:
node -r esm main.js
详细更新...
2019 年 4 月 23 日
最近发布了一项 PR,以更改检测 ECMAScript 模块的方式:
https://github.com/nodejs/node/pull/26745
它仍然落后于 --experimental-modules
标志,但加载模块的方式有重大变化:
package.type
可以是 module
或 commonjs
type: "commonjs"
:
.js
被解析为 CommonJS
- 没有扩展名的默认入口点是 CommonJS
type: "module"
:
.js
被解析为 ECMAScript 模块
- 默认不支持加载JSON或原生模块
- 没有扩展的默认入口点是 ECMAScript 模块
--type=[mode]
让您设置入口点的类型。将覆盖入口点 package.type
。
- 一个新的文件扩展名
.cjs
。
- 这是专门为了支持在
module
模式下导入CommonJS。
- 这仅在 ECMAScript 模块加载器中,CommonJS 加载器保持不变,但如果您使用完整文件路径,扩展将在旧加载器中工作。
--es-module-specifier-resolution=[type]
- 选项是
explicit
(默认)和 node
- 默认情况下,我们的加载器不允许在导入中使用可选扩展,如果有扩展,模块的路径必须包含扩展
- 默认情况下,我们的加载程序不允许导入具有索引文件的目录
- 开发者可以使用
--es-module-specifier-resolution=node
启用CommonJS说明符解析算法
- 这不是一个“功能”,而是一个实验性的实现。预计在 flag 被移除之前会发生变化
--experimental-json-loader
- 当
"type": "module"
时导入 JSON 的唯一方法
- 启用所有
import 'thing.json'
时将独立于模式 通过实验加载程序
- 基于whatwg/html#4315
- 您可以使用
package.main
设置模块的入口点
- main 中使用的文件扩展名将根据模块的类型进行解析
2019 年 1 月 17 日
Node.js 11.6.0 仍然将 ES 模块列为实验性的,在标志后面。
2017 年 9 月 13 日
Node.js 8.5.0 已发布,支持标志后面的 mjs 文件:
node --experimental-modules index.mjs
此计划是删除 v10.0 LTS 版本的标志。
--信息过时。出于历史目的保留在这里--
2017 年 9 月 8 日
Node.js 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 月:
An Update on ES6 Modules in Node.js
Node.js 伙计们决定 最不坏的 解决方案是使用 .mjs
文件扩展名。从中得出的结论是:
In other words, given two files foo.js
and bar.mjs
, using import * from 'foo'
will treat foo.js
as CommonJS while import * from 'bar'
will treat bar.mjs
as an ES6 Module
至于时间表...
At the current point in time, there are still a number of
specification and implementation issues that need to happen on the ES6
and Virtual Machine side of things before Node.js can even begin
working up a supportable implementation of ES6 modules. Work is in
progress but it is going to take some time — We’re currently looking
at around a year at least.
2016 年 10 月:
Node.js 上的一位开发人员最近参加了 TC-39 会议并写了一篇关于要为 Node.js 实施的拦截器的精彩文章:
基本take-away由此得出:
- 静态分析 ECMAScript 模块,评估 CommonJS
- CommonJS 模块允许 monkey-patching 导出,而 ECMAScript 模块目前不允许
- 如果没有某种形式的用户输入,很难检测什么是 ECMAScript 模块和什么是 CommonJS,但他们正在尝试。
*.mjs
似乎是最有可能的解决方案,除非他们可以在没有 user-input 的情况下准确地检测到 ECMAScript 模块
--原答案--
这一段时间以来一直是个烫手山芋。底线是,Node.js 最终会支持ES2015 syntax for importing/exporting modules - most likely when the specification for loading modules 已最终确定并达成一致。
这是 a good overview 的原因 Node.js。从本质上讲,他们需要确保新规范适用于主要是条件同步加载的 Node.js 以及主要是异步加载的 HTML。
现在没有人确切知道,但我想 Node.js 将支持 import/export
静态加载,除了新的 System.import
动态加载 - 同时仍然保持 require
用于遗留代码。
这里有一些关于 Node 如何实现这一点的建议:
我在网上找遍了都没有一个明确的答案。
目前 Node.js 仅使用 CommonJS 语法加载模块,如果你真的想使用标准的 ECMAScript 2015 模块语法,你要么必须事先转译它,要么使用外部模块加载器在运行时。
目前我不太愿意使用这两种方法中的任何一种,Node.js 维护者甚至计划支持 ECMAScript 2015 模块吗?我还没有找到任何关于这个的提示。
目前 Node.js 6.x 声称支持 96% 的 ECMAScript 2015 功能,但没有任何模块参考 (Node.js ECMAScript 2015 support link)。
您知道 Node.js 是否会在不久的将来开箱即用地支持这些模块吗?
Node.js 13.2.0 及以上
Node.js 13.2.0 现在支持没有标志的 ES 模块。但是,该实现仍被标记为实验性的,因此在生产中谨慎使用。
要在 13.2.0 中启用 ECMAScript 模块 (ESM) 支持,请将以下内容添加到您的 package.json
:
{
"type": "module"
}
所有 .js
、.mjs
(或没有扩展名的文件)都将被视为 ESM。
除了整个 package.json
opt-in,还有许多不同的选项,所有这些都在 documentation for 13.2.0.
Node.js 13.1.0 及以下
那些仍在使用旧版本 Node 的人可能想尝试 [esm][3]
模块加载器,它是 Node.js 的 ES 模块规范的 production-ready 实现:
node -r esm main.js
详细更新...
2019 年 4 月 23 日
最近发布了一项 PR,以更改检测 ECMAScript 模块的方式: https://github.com/nodejs/node/pull/26745
它仍然落后于 --experimental-modules
标志,但加载模块的方式有重大变化:
package.type
可以是module
或commonjs
type: "commonjs"
:.js
被解析为 CommonJS- 没有扩展名的默认入口点是 CommonJS
type: "module"
:.js
被解析为 ECMAScript 模块- 默认不支持加载JSON或原生模块
- 没有扩展的默认入口点是 ECMAScript 模块
--type=[mode]
让您设置入口点的类型。将覆盖入口点package.type
。- 一个新的文件扩展名
.cjs
。- 这是专门为了支持在
module
模式下导入CommonJS。 - 这仅在 ECMAScript 模块加载器中,CommonJS 加载器保持不变,但如果您使用完整文件路径,扩展将在旧加载器中工作。
- 这是专门为了支持在
--es-module-specifier-resolution=[type]
- 选项是
explicit
(默认)和node
- 默认情况下,我们的加载器不允许在导入中使用可选扩展,如果有扩展,模块的路径必须包含扩展
- 默认情况下,我们的加载程序不允许导入具有索引文件的目录
- 开发者可以使用
--es-module-specifier-resolution=node
启用CommonJS说明符解析算法 - 这不是一个“功能”,而是一个实验性的实现。预计在 flag 被移除之前会发生变化
- 选项是
--experimental-json-loader
- 当
"type": "module"
时导入 JSON 的唯一方法
- 启用所有
import 'thing.json'
时将独立于模式 通过实验加载程序
- 基于whatwg/html#4315
- 当
- 您可以使用
package.main
设置模块的入口点- main 中使用的文件扩展名将根据模块的类型进行解析
2019 年 1 月 17 日
Node.js 11.6.0 仍然将 ES 模块列为实验性的,在标志后面。
2017 年 9 月 13 日
Node.js 8.5.0 已发布,支持标志后面的 mjs 文件:
node --experimental-modules index.mjs
此计划是删除 v10.0 LTS 版本的标志。
--信息过时。出于历史目的保留在这里--
2017 年 9 月 8 日
Node.js 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 月:
An Update on ES6 Modules in Node.js
Node.js 伙计们决定 最不坏的 解决方案是使用 .mjs
文件扩展名。从中得出的结论是:
In other words, given two files
foo.js
andbar.mjs
, usingimport * from 'foo'
will treatfoo.js
as CommonJS whileimport * from 'bar'
will treatbar.mjs
as an ES6 Module
至于时间表...
At the current point in time, there are still a number of specification and implementation issues that need to happen on the ES6 and Virtual Machine side of things before Node.js can even begin working up a supportable implementation of ES6 modules. Work is in progress but it is going to take some time — We’re currently looking at around a year at least.
2016 年 10 月:
Node.js 上的一位开发人员最近参加了 TC-39 会议并写了一篇关于要为 Node.js 实施的拦截器的精彩文章:
基本take-away由此得出:
- 静态分析 ECMAScript 模块,评估 CommonJS
- CommonJS 模块允许 monkey-patching 导出,而 ECMAScript 模块目前不允许
- 如果没有某种形式的用户输入,很难检测什么是 ECMAScript 模块和什么是 CommonJS,但他们正在尝试。
*.mjs
似乎是最有可能的解决方案,除非他们可以在没有 user-input 的情况下准确地检测到 ECMAScript 模块
--原答案--
这一段时间以来一直是个烫手山芋。底线是,Node.js 最终会支持ES2015 syntax for importing/exporting modules - most likely when the specification for loading modules 已最终确定并达成一致。
这是 a good overview 的原因 Node.js。从本质上讲,他们需要确保新规范适用于主要是条件同步加载的 Node.js 以及主要是异步加载的 HTML。
现在没有人确切知道,但我想 Node.js 将支持 import/export
静态加载,除了新的 System.import
动态加载 - 同时仍然保持 require
用于遗留代码。
这里有一些关于 Node 如何实现这一点的建议: