原文: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…公開。