小编典典

Node.js 计划支持导入/导出 ES6 (ECMAScript 2015) 模块

all

我一直在寻找整个互联网,但没有明确的答案。

目前 Node.js
仅使用CommonJS语法来加载模块,如果你真的想使用标准的
ECMAScript 2015 模块语法,你要么必须事先转译它,要么在运行时使用外部模块加载器。

目前我不太赞成使用这两种方法中的任何一种,Node.js 维护者是否甚至计划支持 ECMAScript 2015 模块?我根本没有找到关于这个的提示。

目前 Node.js 6.x 声称支持 96% 的 ECMAScript 2015 功能,但没有任何对模块的引用(Node.js ECMAScript
2015 支持链接
)。

你知道 Node.js 是否会在不久的将来支持这些开箱即用的模块吗?


阅读 109

收藏
2022-04-27

共1个答案

小编典典

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,所有这些选项都在13.2.0
的文档中进行了
详细说明。

Node.js 13.1.0 及以下

那些仍在使用旧版本 Node 的人可能想尝试[esm][3]模块加载器,它是 Node.js 的 ES 模块规范的生产就绪实现:

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=nodeCommonJS 说明符解析算法来启用
    • 这不是“特性”,而是实验的实现。预计在删除标志之前会发生变化
  • --experimental-json-loader
    • 导入 JSON 的唯一方法"type": "module"
    • 当启用所有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 主分支已更新,初始支持 ESM 模块: https
://github.com/nodejs/node/commit/c8a389e19f172edbada83f59944cad7cc802d9d5

这应该在最新的每晚可用(可以通过 nvm 安装以与您现有的安装一起运行): https
://nodejs.org/download/nightly/

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

包.json

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

然后运行:

node --experimental-modules .

2017 年 2 月:

Node.js 中 ES6 模块的更新

Node.js 的人已经决定 最不坏 的解决方案是使用.mjs文件扩展名。从中得出的结论是:

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

至于时间线……

目前,在 Node.js 甚至可以开始构建可支持的 ES6 模块实现之前,仍然需要在 ES6
和虚拟机方面发生许多规范和实现问题。工作正在进行中,但需要一些时间——目前 至少 需要一年左右的时间。

2016 年 10 月:

Node.js 的一位开发人员最近参加了 TC-39 会议,并写了一篇关于 Node.js 实施的阻止程序的精彩文章:

Node.js、TC-39 和模块

基本的收获是:

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

-- 原始答案 –

很长一段时间以来,这一直是一个烫手山芋。底线是,是的,Node.js
最终将支持用于导入/导出模块的ES2015语法——最有可能在加载模块的规范最终确定并达成一致时。

这是一个很好的概述,是什么阻碍了
Node.js。本质上,他们需要确保新规范适用于主要是条件同步加载的 Node.js 以及主要是异步的 HTML。

目前没有人确切知道,但我想 Node.js 将支持import/export静态加载,除了新System.import的动态加载 -
同时仍保留require遗留代码。

以下是关于 Node 如何实现这一点的一些建议:

2022-04-27