问题描述
我已经在互联网上到处找了,也没有明确的答案。
目前Node.js只使用CommonJS语法加载模块,如果您真的想使用标准的ECMAScript 2015模块语法,您必须事先转换它或在运行时使用外部模块加载器。
目前我对使用这两种方法中的任何一种都不太肯定,Node.js的维护者是否计划支持ECMASIPT 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
选择加入之外,还有许多不同的选项,所有这些选项都在documentation for 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=node
启用CommonJS说明符解析算法
这不是一个"特性",而是一个实验性的实现。预计在移除旗帜之前会更改
--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 应在每晚的最新版本中提供(可以是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
文件扩展名。由此得出的结论是:
foo.js
和bar.mjs
,使用import * from 'foo'
会将foo.js
视为CommonJS,而使用
将bar.mjs
视为ES6模块
至于时间表...
在当前时间点,仍有多个 ES6上需要出现的规范和实施问题 以及在Node.js可以开始之前的虚拟机端 制定可支持的ES6模块实施。工作开始了 进展,但这将需要一些时间 - 我们目前正在寻找 大约一年至少。2016年10月:
Node.js上的一位开发人员最近参加了TC-39会议,并撰写了一篇关于为Node.js实现拦截器的精彩文章:
Node.js, TC-39, and Modules
从中得出的基本结论是:
静态分析ECMAScript模块,评估CommonJS CommonJS模块允许修补猴子导出,而ECMAScript模块目前不支持 如果没有某种形式的用户输入,很难检测出什么是ECMAScript模块和什么是CommonJS,但他们正在尝试。*.mjs
似乎是最有可能的解决方案,除非他们可以在不需要用户输入的情况下准确地检测ECMAScript模块
--原始答案--
很长一段时间以来,这一直是一个烫手山芋。底线是肯定的,Node.js最终将支持用于导入/导出模块的ES2015语法--最有可能的时候是specification for loading modules最终确定并达成一致。以下是Node.js的a good overview支撑因素。本质上,他们需要确保新规范适用于主要是有条件的、同步加载的Node.js,以及主要是异步的HTML。
目前还没有人确切知道,但我想Node.js将支持import/export
用于静态加载,除了新的System.import
用于动态加载-同时仍然保留require
用于遗留代码。
以下是关于Node如何实现这一点的一些建议:
In defense of .js .mjs modules