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

标签 javascript node.js module ecmascript-6 es6-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 之外,还有许多不同的选项。选择加入,所有这些都在 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可以是 modulecommonjs
  • 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
  • "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 主分支已经更新,初始支持 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 session ,并写了一篇关于 Node.js 实现的阻塞器的精彩文章:
    Node.js, TC-39, and Modules
    基本的结论是:
  • 静态分析 ECMAScript 模块,评估 CommonJS
  • CommonJS 模块允许猴子补丁导出,而 ECMAScript 模块目前不支持
  • 如果没有某种形式的用户输入,很难检测什么是 ECMAScript 模块,什么是 CommonJS,但他们正在尝试。
  • *.mjs似乎是最可能的解决方案,除非他们可以在没有用户输入的情况下准确检测 ECMAScript 模块

  • ——原答案——
    一段时间以来,这一直是一个烫手山芋。最重要的是,Node.js 最终会支持 ES2015导入/导出模块的语法 - 最有可能发生在 specification for loading modules最终确定并达成一致。
    这是a good overview是什么阻碍了 Node.js。本质上,他们需要确保新规范适用于 Node.js,Node.js 主要是有条件的同步加载,也适用于主要是异步的 HTML。
    现在没有人确切知道,但我想 Node.js 会支持 import/export用于静态加载,除了新的 System.import用于动态加载 - 同时仍保持 require对于遗留代码。
    下面是一些关于 Node 如何实现这一目标的建议:
  • In defense of .js
  • .mjs modules
  • 关于javascript - Node.js 计划支持导入/导出 ES6 (ECMAScript 2015) 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37132031/

    相关文章:

    node.js - Ubuntu 服务器上的 Nodejs/Socket.io 与 Nginx 反向代理 - "failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT"

    docker - 在 Dockerfile 和 docker-compose 中编写什么来传递本地包

    perl - 是否有不能在 CGI 中使用的 Perl 模块?

    android - 在钛中,是否可以从 android 模块访问 3rd-party-jar-bundled 资源文件( xml )?

    Javascript:如何更改页面中所有链接的样式?

    javascript - 是否存在真正的 ECMAScript 实现,或者它只是一个规范?

    javascript - 将 NodeJS MySql 与 React 应用程序集成

    javascript - Iframe 内的事件

    javascript - 下拉菜单更改时 selectpicker 不起作用

    javascript - 在没有 Nodejs 的实时应用程序中,您仍然可以使用 php 作为 angularjs2 的后端吗?