node 12 新增的模塊加載流程 LOAD_SELF_REFERENCE

新增的模塊加載流程

require("X") //當在 Y 文件中加載 X 模塊時
複製代碼
  1. 若是 X 是核心模塊,載入javascript

  2. 若是 X 是以 "/" 開頭的絕對路徑,須要添加系統根路徑java

  3. 若是 X 是以 "/" , "./" , "../" 開頭的路徑node

    a. 嘗試做爲一個文件載入json

    b.嘗試做爲一個目錄載入數組

    c.出錯 "not found"ui

  4. 嘗試加載自身引用(LOAD_SELF_REFERENCE)spa

  5. 嘗試加載 node_modules 三方控件引用code

其中第四步爲 node v12 新增的流程,須要使用 --experimental-modules 開啓此步流程, 在node v13 中不須要 --experimental-modulesip

使用 exports 聲明

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 不是核心模塊而且不是以 "/" , "./" , "../" 開頭的路徑時,會嘗試加載自身引用。

  1. 將 X 分解分 name/subpath 兩部分,以第一個"/"分割。

  2. 若是name和最近的package.json中name相同,且有聲明exports

  3. exports中有以subpath開頭的聲明

    a.若是是文件聲明,嘗試做爲一個文件載入

    b.若是是目錄聲明,將x前綴轉換成聲明的目錄,繼續載入

    PACKAGE_EXPORTS_TARGET_RESOLVE(
    	pathToFileURL(DIR/name), 
    	exports[key],
      subpath.slice(key.length), 
      ["node", "require"]
     )
    複製代碼

加載 node_modules 三方控件引用

加載三方控件時,也會去解析package.json 中 exports 聲明

相關文章
相關標籤/搜索