原文:Announcing a new --experimental-modulesjavascript
译文地址html
在2017年,Node.js 8.9.0发布了对ECMAScript模块的实验性支持。这种ECMAScript模块的支持是须要在后面加上--experimental-modules
标识来运行。java
如今,主流浏览器都能经过<script type=”module”>
标签支持ECMAScript 模块 (ES modules) 。各类项目npm包都使用了ES模块编写,而且能够经过<script type= " module " >
在浏览器中直接使用。支持导入映射(import maps)即将登录Chrome。import map将让浏览器支持node.js风格的包名导入。node
这些采用ES模块方面的进展大大加快了Node.js对ES模块的支持速度。既然已经有其余运行时和环境在使用ES模块,那么Node.js支持这个JavaScript标准就更重要了。git
Nodejs最初将ES模块做为一个保留实验特性的缘由是为了提供时间让社区去讨论和反馈这种设计。Modules Team创建出来就是为了对这些反馈提供支持,最终致使了一个ES模块的新实现。咱们很高兴地宣布它将做为Node.js 12版本的一部分发布。它将取代旧的实验模块实现,而且将使用相同的标志(--experimental-modules
)。咱们但愿这个新实现可以解决社区的许多问题,而且可以在2019年10月Node.js 12达到LTS状态以前做为Node.js的一部分正式发布(不须要再带--experimental-modules
)github
--experimental-modules
包含了什么与以前的版本同样,这个新的实验性模块为Node.js增长了如下支持:npm
ES2015 import语句能够引用那些使用ES模块语法编写的Javascript文件。文件能够被引用为相对url ('./file.mjs '
)、绝对file:// url ('file:///opt/app/file.mjs '
)、包名(' es-module-package '
)或包名路径('es-module-package/lib/file.mjs '
)的形式。json
import语句引用的ES模块文件能够指定默认导出(import _ from ‘es-module-package’
)、命名导出(import { shuffle } from ‘es-module-package’
) 和命名空间导出(import * as fs from ‘fs’
)。全部的Node.js内置模块(如fs和path)都支持这三种类型的导出。api
import语句引用CommonJS文件(当前全部使用require、module.exports编写的Node.js模块)只能使用CommonJS默认导出(import _ from ‘commonjs-package’
)。这项工做在进展中而且将来可能会发生改变promise
ES模块文件中的export语句能够指定引用的导入语句为默认导出或命名导出。
动态import()
表达式能够用来从CommonJS或者ES模块导入ES模块文件。须要注意的是,这个语句返回的是一个promise
import.meta.url
的值为当前ES模块文件的绝对url。
能够编写加载器(Loaders)来修改Node.Js对于ES模块的行为。这项工做仍然在进行中
Node.js能够将ES模块文件做为程序的初始入口运行
文件做为ES模块被加载是在严格模式下的,若是是CommonJS的话须要在每一个文件的最头部加上'use strict'
.mjs
结尾的文件在import语句和经过node命令行运行时都将被显式看成ES模块
而且,新版本的 --experimental-modules
添加了如下特性:
咱们听到了一些很是强烈的反馈Nodejs须要提供一种方式在.js文件中使用import和export语法
新的--experimental-modules
提供了两种方式实现,一种是经过package.json
中的type
字段,另外一种是输入经过传入参数--eval, --print or STDIN
添加一个--input-type
标示
package.json
type
字段在你的项目package.json中添加'type':'module'字段,Node.js就会把项目中全部的.js文件看成ES模块
若是项目中的一些文件使用了CommonJS而且你不能当即转换它们,你能够把那些文件重命名为.mjs或者把它们放到一个子文件夹而后添加一个package.json
包含{ “type”: “commonjs” }
,这样那些.js文件会被看成CommonJS处理
当Node.js想要加载任何文件的时候,它将会查找文件当前目录下的package.json
文件,找不到的话将向上查找直到根目录。这种行为很是相似于babel的.babelrc
文件。这种新的方式容许nodejs使用package级别的元数据和配置,相似于babel和其它工具目前使用的样子
--input-type
flag使用-—input-type=module
做为ES模块运行字符串输入(-—eval、-—print
或STDIN
)。—-input-type
的值为-—input-type=module
或—input-type=commonjs
。
只有.mjs文件扩展名被看成ES模块,新的.cjs文件扩展名将被看成CommonJS模块。.cjs扩展名是当.mjs和.js看成es模块的时候,保留项目中的CommonJS文件用到的。
默认状况下在新的--experimental-modules
下,import语句中的文件扩展名是强制性的:import ‘./file.js’
并不一样于 import ‘./file’
。可是,CommonJS风格的自动扩展名处理行为能够经过--es-module-specifier-resolution=node
来开启(默认是es-module-specifier-resolution=explicit
)。包名引入仍然不变,例如import fs from ‘fs
咱们提供了--es-module-specifier-resolution=node
可选使用Commonjs风格扩展名和的解析。可是咱们默认关闭了它,在咱们去除--experimental-modules
以前,用于收集用户对于彻底指定路径(fully specified paths)的反馈。 你能够在这里找到关于这个话题的讨论。
这种设计的主要缘由是,经过咱们提供的特定解决办法,去鼓励开发者们编写浏览器和node共享的代码
CommonJS的全局变量(如require, exports, module, __filename, __dirname
)在ES模块中将不会定义。可是可使用module.createRequireFromPath()
去创造一个commonJS require函数在ES模块上下文中使用
之前的--experimental-modules
容许导入JSON语句和原生模块。如今这个已经删除了,默认不能导入JSON语句和原生模块,您可使用module.createRequireFromPath()
来实现原先的功能。
实验性标记--experimental-json-modules
能够支持json文件的导入。咱们正在用浏览器对这个特性进行标准化,而且Node.js但愿咱们的支持能与最终的标准保持一致。
其它也有正在进行的工做,以涵盖WASM和其余将来潜在的模块类型。Node.js之后将以符合规范的方式增长对这些模块类型的支持。
这是一项正在进行的工做,可能会发生变化。经过package.json
的main
字段类型指定入口文件(这个文件是ES模块)。你可使用ES模块建立一个包。若是文件扩展名是.mjs或者package.json
包含'type':'module'
Node.js的话,Node.js将它做为ES模块加载。
目前,没法建立一个既能够经过require('pkg')
又能够import ‘pkg’
来使用的npm包。咱们正在努力解决这一问题,而且可能有对上述内容的修改。特别是,Node.js可能会选择'main'
之外的字段来定义包的ES模块入口点。但咱们意识到社区已经接受了'main'
字段,因此这也不太可能这样作由于不少包已经使用了module
去引入ES模块的javascript,但可能没有评估在node.js中使用(由于文件名的扩展缺省的,或者代码里面包含require
表达式)。在解决这个问题以前,请不要发布任何打算给Node.js使用的ES模块的npm包。
上面全部的这些都是做为Node.js 12 --experimental-modules
的一部分。在咱们的规划中,在 2019年10月 Node.js 12 达到 LTS 并移除--experimental-modules
标识以前,咱们但愿有一些潜在的改进:
require
到CommonJS,也能够被import
到ES模块中。Module.createRequireFromPath()
包含许多的模版文件。咱们但愿提供一种更简单的方式在ES模块代码中进行require
import sdk from ‘some-service/sdk’
从‘some-service/sdk’
到./src/sdk/public-api.mjs
的。就是这样!咱们但愿你喜欢这个新的--experimental-modules
,并期待您的反馈。模块团队的工做在github.com/nodejs/modu…公开。