欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > node模块查找策略

node模块查找策略

2025/2/5 23:10:50 来源:https://blog.csdn.net/qq_36973122/article/details/145433431  浏览:    关键词:node模块查找策略

在路径 Y 中引入 X 模块:

  1. 如果 X 是核心模块

    a. 返回核心模块

    b. 停止

  2. 如果 X 以 / 开头

    a. 将 Y 设置为文件系统根目录

  3. 如果 X 以 .//../ 开头

    a. LOAD_AS_FILE(Y + X)

    b. LOAD_AS_DIRECTORY(Y + X)

    c. THROW “not found”

  4. 如果 X 以 # 开头

    a. LOAD_PACKAGE_IMPORTS(X, dirname(Y))

  5. LOAD_PACKAGE_SELF(X, dirname(Y))

  6. LOAD_NODE_MODULES(X, dirname(Y))

  7. 抛出 “not found” 错误

LOAD_AS_FILE(X)

  1. 如果 X 是一个文件,则按照其文件扩展名格式加载 X。 停止

  2. 如果 X.js 是一个文件
    a. 找到距离 X 最近的包作用域 SCOPE。
    b. 如果没有找到 scope

    1. MAYBE_DETECT_AND_LOAD(X.js)

    c. 如果 SCOPE/package.json 包含 type 字段

     1. 如果 `type` 字段为 `module` ,则将 X.js 作为 ECMAScript 模块加载。停止。2. 如果 `type` 字段为 `commonjs` ,则将 X.js 作为 commonjs 模块加载。停止。
    

    d. MAYBE_DETECT_AND_LOAD(X.js)

  3. 如果 X.json 是一个文件,则将 X.json 加载为一个 JavaScript 对象。停止。

  4. 如果 X.node 是一个文件,则将 X.node 作为二进制插件加载。停止。

LOAD_INDEX(X)

  1. 如果 X/index.js 是一个文件
    a. 找到距离 X 最近的包作用域 SCOPE。
    b. 如果没有找到 scope, 则将 X/index.js 作为 commonjs 模块加载。停止。
    c. 如果 SCOPE/package.json 包含 type 字段
    1. 如果 type 字段为 module ,则将 X/index.js 作为 ECMAScript 模块加载。停止。
    2. 如果 type 字段为 commonjs ,则将 X/index.js 作为 commonjs 模块加载。停止。
  2. 如果 X/index.json 是一个文件,则将 X/index.json 加载为一个 JavaScript 对象。停止。
  3. 如果 X/index.node 是一个文件,则将 X/index.node 作为二进制插件加载。停止。

LOAD_AS_DIRECTORY(X)

  1. 如果 X/package.json 是一个文件
    a. 解析 X/package.json ,查找 main 字段。
    b. 如果 main 是一个假值,则跳到第 2 步
    c. let M = X + (json main field)
    d. LOAD_AS_FILE(M)
    e. LOAD_INDEX(M)
    f. LOAD_INDEX(X) DEPRECATED
    g. THROW “not found”
  2. LOAD_INDEX(X)

LOAD_PACKAGE_IMPORTS(X, DIR)

  1. 找到与 DIR 最近的包作用域 SCOPE。
  2. 如果没有找到 scope,返回。
  3. 如果 SCOPE/package.json 中的 importsnullundefined,则返回。
  4. let MATCH = PACKAGE_IMPORTS_RESOLVE(X, pathToFileURL(SCOPE), [“node”, “require”])
  5. RESOLVE_ESM_MATCH(MATCH).

LOAD_PACKAGE_SELF(X, DIR)

  1. 找到与 DIR 最近的包作用域 SCOPE。
  2. 如果没有找到 scope,返回。
  3. 如果 SCOPE/package.json 中的 exportsnullundefined,则返回。
  4. 如果 SCOPE/package.json 中的 name 不是 X 的第一个部分,则返回。
  5. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(SCOPE), “.” + X.slice(“name”.length), `package.json` “exports”, [“node”, “require”])
  6. RESOLVE_ESM_MATCH(MATCH)

LOAD_NODE_MODULES(X, START)

  1. let DIRS = NODE_MODULES_PATHS(START)
  2. for each DIR in DIRS:
    a. LOAD_PACKAGE_EXPORTS(X, DIR)
    b. LOAD_AS_FILE(DIR/X)
    c. LOAD_AS_DIRECTORY(DIR/X)

RESOLVE_ESM_MATCH(MATCH)

  1. let RESOLVED_PATH = fileURLToPath(MATCH)
  2. 如果 RESOLVED_PATH 中的文件存在,则按其扩展名格式加载 RESOLVED_PATH。停止。
  3. THROW “not found”

MAYBE_DETECT_AND_LOAD(X)

  1. 如果 X 解析为 CommonJS 模块,则将 X 加载为 CommonJS 模块。停止。

  2. 否则,如果启用了--experimental-require-module选项,并且 X 的源代码可以被解析为 ECMAScript 模块

    a. 加载 X 为 ECMAScript 模块。停止。

  3. 在 1 步中抛出尝试将 X 解析为 CommonJS 时的 SyntaxError,停止。

NODE_MODULES_PATHS(START)

  1. let PARTS = path split(START)
  2. let I = count of PARTS - 1
  3. let DIRS = []
  4. while I >= 0,
    a. if PARTS[I] = “node_modules” CONTINUE
    b. DIR = path join(PARTS[0 … I] + “node_modules”)
    c. DIRS = DIR + DIRS
    d. let I = I - 1
  5. return DIRS + GLOBAL_FOLDERS

模块查找策略粗略图解

graph TB
A(模块查找策略) --> B{是否以 ./ 或 ../ 开头}
B --是--> C{是否带文件扩展名}
C --是--> D{根据路径查找文件}
C --否--> E{加上 .js 或 .json 
后缀查找文件}
D --找到--> I(成功)
D --找不到--> J(失败)
E --找到--> F(成功)
E --找不到--> G{当成文件夹查找文件夹内的package.json 文件
}
G --找到--> H{是否有 main 字段}
H --是--> M{根据 main 字段查找文件}
H --否--> L
M --找到--> N(成功)
M -- 找不到--> O(失败)
G --找不到--> L{文件夹内是否有inexd.js 文件
}
L --找到--> P(成功)
L --找不到--> Q(失败)B --否--> R{是否为核心模块}
R --是--> S(成功)
R --否--> T(进入 node_module 文件夹查找)
T --> E
Created with Raphaël 2.3.0 模块查找策略开始 是否以 ./ 或 ../ 开头 是否带文件扩展名 根据路径查找文件 成功 失败 加上 .js 或 .json 后缀查找文件 成功 当成文件夹 查找文件夹内的 package.json 文件 是否有 main 字段 根据 main 字段查找文件 成功 失败 文件夹内是否有 index.js 文件 成功 失败 是否为核心模块 成功 进入 node_module 文件夹查找 yes no yes no yes no yes no yes no yes no yes no yes no yes no

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com