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