跳到主要内容

Resolve the path of a module like require.resolve() but from a given path

源码解析

"use strict";
const path = require("path");
const Module = require("module");
const fs = require("fs");

const resolveFrom = (fromDirectory, moduleId, silent) => {
if (typeof fromDirectory !== "string") {
throw new TypeError(
`Expected \`fromDir\` to be of type \`string\`, got \`${typeof fromDirectory}\``
);
}

if (typeof moduleId !== "string") {
throw new TypeError(
`Expected \`moduleId\` to be of type \`string\`, got \`${typeof moduleId}\``
);
}

try {
fromDirectory = fs.realpathSync(fromDirectory);
} catch (error) {
if (error.code === "ENOENT") {
fromDirectory = path.resolve(fromDirectory);
} else if (silent) {
return;
} else {
throw error;
}
}

// 这里不会影响代码执行 => 可以传入任意文件名称
const fromFile = path.join(fromDirectory, "noop.js");

const resolveFileName = () =>
Module._resolveFilename(moduleId, {
id: fromFile,
filename: fromFile,
paths: Module._nodeModulePaths(fromDirectory),
});

if (silent) {
try {
return resolveFileName();
} catch (error) {
return;
}
}

return resolveFileName();
};

module.exports = (fromDirectory, moduleId) =>
resolveFrom(fromDirectory, moduleId);
module.exports.silent = (fromDirectory, moduleId) =>
resolveFrom(fromDirectory, moduleId, true);

.silent => 静默方法 === 如果有异常出现的话异常不会被抛出

1. 计算给定路径的规范路径名

fromDirectory = fs.realpathSync(fromDirectory);

通过fs.realpathSync() 方法 解析计算规范路径名

2. 获取所有可能的 node_modules 路径

paths: Module._nodeModulePaths(fromDirectory);

通过 Module._nodeModulePaths 内置方法获取当前目录下所有可能的 node_modules 路径

3. 获取绝对路径

const resolveFileName = () =>
Module._resolveFilename(moduleId, {
id: fromFile,
filename: fromFile,
paths: Module._nodeModulePaths(fromDirectory),
});

return resolveFileName();

通过执行 Module._resolveFilename() 方法返回绝对路径

附:Module._nodeModulePaths 和 Module._resolveFilename 的执行流程