mirror of
https://github.com/nodejs/node.git
synced 2025-05-08 08:02:48 +00:00

PR-URL: https://github.com/nodejs/node/pull/20504 Refs: https://github.com/nodejs/TSC/issues/389 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Shingo Inoue <leko.noor@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
100 lines
2.6 KiB
JavaScript
100 lines
2.6 KiB
JavaScript
'use strict';
|
|
|
|
const { URL } = require('url');
|
|
const CJSmodule = require('internal/modules/cjs/loader');
|
|
const internalFS = require('internal/fs/utils');
|
|
const { NativeModule, internalBinding } = require('internal/bootstrap/loaders');
|
|
const { extname } = require('path');
|
|
const { realpathSync } = require('fs');
|
|
const preserveSymlinks = !!process.binding('config').preserveSymlinks;
|
|
const {
|
|
ERR_MISSING_MODULE,
|
|
ERR_MODULE_RESOLUTION_LEGACY,
|
|
ERR_UNKNOWN_FILE_EXTENSION
|
|
} = require('internal/errors').codes;
|
|
const { resolve: moduleWrapResolve } = internalBinding('module_wrap');
|
|
const StringStartsWith = Function.call.bind(String.prototype.startsWith);
|
|
const { getURLFromFilePath, getPathFromURL } = require('internal/url');
|
|
|
|
const realpathCache = new Map();
|
|
|
|
function search(target, base) {
|
|
if (base === undefined) {
|
|
// We cannot search without a base.
|
|
throw new ERR_MISSING_MODULE(target);
|
|
}
|
|
try {
|
|
return moduleWrapResolve(target, base);
|
|
} catch (e) {
|
|
e.stack; // cause V8 to generate stack before rethrow
|
|
let error = e;
|
|
try {
|
|
const questionedBase = new URL(base);
|
|
const tmpMod = new CJSmodule(questionedBase.pathname, null);
|
|
tmpMod.paths = CJSmodule._nodeModulePaths(
|
|
new URL('./', questionedBase).pathname);
|
|
const found = CJSmodule._resolveFilename(target, tmpMod);
|
|
error = new ERR_MODULE_RESOLUTION_LEGACY(target, base, found);
|
|
} catch (problemChecking) {
|
|
// ignore
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
const extensionFormatMap = {
|
|
'__proto__': null,
|
|
'.mjs': 'esm',
|
|
'.json': 'json',
|
|
'.node': 'addon',
|
|
'.js': 'cjs'
|
|
};
|
|
|
|
function resolve(specifier, parentURL) {
|
|
if (NativeModule.nonInternalExists(specifier)) {
|
|
return {
|
|
url: specifier,
|
|
format: 'builtin'
|
|
};
|
|
}
|
|
|
|
let url;
|
|
try {
|
|
url = search(specifier,
|
|
parentURL || getURLFromFilePath(`${process.cwd()}/`).href);
|
|
} catch (e) {
|
|
if (typeof e.message === 'string' &&
|
|
StringStartsWith(e.message, 'Cannot find module'))
|
|
e.code = 'MODULE_NOT_FOUND';
|
|
throw e;
|
|
}
|
|
|
|
const isMain = parentURL === undefined;
|
|
|
|
if (!preserveSymlinks || isMain) {
|
|
const real = realpathSync(getPathFromURL(url), {
|
|
[internalFS.realpathCacheKey]: realpathCache
|
|
});
|
|
const old = url;
|
|
url = getURLFromFilePath(real);
|
|
url.search = old.search;
|
|
url.hash = old.hash;
|
|
}
|
|
|
|
const ext = extname(url.pathname);
|
|
|
|
let format = extensionFormatMap[ext];
|
|
if (!format) {
|
|
if (isMain)
|
|
format = 'cjs';
|
|
else
|
|
throw new ERR_UNKNOWN_FILE_EXTENSION(url.pathname);
|
|
}
|
|
|
|
return { url: `${url}`, format };
|
|
}
|
|
|
|
module.exports = resolve;
|
|
// exported for tests
|
|
module.exports.search = search;
|