require("X") //當在 Y 文件中加載 X 模塊時
複製代碼
若是 X 是核心模塊,載入javascript
若是 X 是以 "/" 開頭的絕對路徑,須要添加系統根路徑java
若是 X 是以 "/" , "./" , "../" 開頭的路徑node
a. 嘗試做爲一個文件載入json
b.嘗試做爲一個目錄載入數組
c.出錯 "not found"ui
嘗試加載自身引用(LOAD_SELF_REFERENCE)spa
嘗試加載 node_modules 三方控件引用code
其中第四步爲 node v12 新增的流程,須要使用 --experimental-modules
開啓此步流程, 在node v13 中不須要 --experimental-modules
。ip
node 在 v12 容許在 package.json 中使用 exports
,顯示聲明要導入的文件路徑以及如何去解析它們,這擴展了使用 main
字段已經擁有的控件包。string
{
"exports": {
"./feature": "./lib/feature.js",
}
}
複製代碼
{
"exports": {
"./feature/": "./lib/feature/",
}
}
複製代碼
使用 "." 能夠聲明默認的輸出模塊,對於支持 exports
的node版本中,exports
的優先級是高於 main
{
"exports": {
".": "./main.js"
}
}
//也能夠簡寫
{
"exports": "./main.js"
}
//等同於用
{
"main": "./main.js",
}
複製代碼
exports
能夠根據不一樣環境導出不一樣的文件,node 支持4種條件匹配:
default
: 默認的匹配選項,任意條件都能匹配的選項。import
: 使用 esmodule 加載模塊的選項。require
: 使用 CommonJS 加載模塊的選項。node
: 使用任意node環境加載文件的選項。它們四個的優先級取決於在 exports
中的聲明順序,越早聲明優先級越高。
{
"exports": {
"./feature": {
"import": "./feature-default.js",
"browser": "./feature-browser.js"
}
}
}
複製代碼
當使用數組時,不合法的路徑將被忽略,好比不以 "./" 開頭的路徑或者不是以 "/"結尾的目錄。
可是這並非一種錯誤的回退寫法,前一個值是路徑可是卻沒有這個文件時,node仍是會拋出錯誤,並不會加載後面的路徑
{
"exports": {
"./submodule": ["not:valid", "./submodule.js"]
}
}
複製代碼
require("X") //當在 Y 文件中加載 X 模塊時
複製代碼
當 X 不是核心模塊而且不是以 "/" , "./" , "../" 開頭的路徑時,會嘗試加載自身引用。
將 X 分解分 name/subpath 兩部分,以第一個"/"分割。
若是name和最近的package.json中name相同,且有聲明exports
exports
中有以subpath開頭的聲明
a.若是是文件聲明,嘗試做爲一個文件載入
b.若是是目錄聲明,將x前綴轉換成聲明的目錄,繼續載入
PACKAGE_EXPORTS_TARGET_RESOLVE(
pathToFileURL(DIR/name),
exports[key],
subpath.slice(key.length),
["node", "require"]
)
複製代碼
加載三方控件時,也會去解析package.json 中 exports
聲明