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 声明

相关文章
相关标签/搜索