Skip to content

Commit

Permalink
fix(node): require.resolve - fallback to global cache when bare speci…
Browse files Browse the repository at this point in the history
…fier from paths not found (#23618)

Part of #22607 (probably closes it, but I haven't done thorough testing)

Makes it so that `require.resolve` with `paths` specified will fallback
to using the global cache when the paths can't be found when using a
global cache (not when using a node_modules folder)
  • Loading branch information
dsherret authored May 1, 2024
1 parent 486437f commit 56bf634
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 8 deletions.
33 changes: 25 additions & 8 deletions ext/node/polyfills/01_require.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,6 @@ function setupBuiltinModules() {
}
setupBuiltinModules();

// Map used to store CJS parsing data.
const cjsParseCache = new SafeWeakMap();

function pathDirname(filepath) {
if (filepath == null) {
throw new Error("Empty filepath.");
Expand All @@ -286,11 +283,10 @@ const nativeModulePolyfill = new SafeMap();
const relativeResolveCache = ObjectCreate(null);
let requireDepth = 0;
let statCache = null;
let isPreloading = false;
let mainModule = null;
let hasBrokenOnInspectBrk = false;
let hasInspectBrk = false;
// Are we running with --node-modules-dir flag?
// Are we running with --node-modules-dir flag or byonm?
let usesLocalNodeModulesDir = false;

function stat(filename) {
Expand Down Expand Up @@ -766,9 +762,7 @@ Module._resolveFilename = function (

if (typeof options === "object" && options !== null) {
if (ArrayIsArray(options.paths)) {
const isRelative = op_require_is_request_relative(
request,
);
const isRelative = op_require_is_request_relative(request);

if (isRelative) {
paths = options.paths;
Expand Down Expand Up @@ -848,6 +842,29 @@ Module._resolveFilename = function (
const err = new Error(message);
err.code = "MODULE_NOT_FOUND";
err.requireStack = requireStack;

// fallback and attempt to resolve bare specifiers using
// the global cache when not using --node-modules-dir
if (
!usesLocalNodeModulesDir &&
ArrayIsArray(options?.paths) &&
request[0] !== "." &&
request[0] !== "#" &&
!request.startsWith("file:///") &&
!op_require_is_request_relative(request) &&
!op_require_path_is_absolute(request)
) {
try {
return Module._resolveFilename(request, parent, isMain, {
...options,
paths: undefined,
});
} catch {
// ignore
}
}

// throw the original error
throw err;
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"args": "run --allow-read main.ts",
"output": "main.out"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[UNORDERED_START]
Download http://localhost:4545/npm/registry/@denotest/esm-basic
Download http://localhost:4545/npm/registry/@denotest/require-resolve
[UNORDERED_END]
[UNORDERED_START]
Download http://localhost:4545/npm/registry/@denotest/esm-basic/1.0.0.tgz
Download http://localhost:4545/npm/registry/@denotest/require-resolve/1.0.0.tgz
[UNORDERED_END]
[WILDLINE]@denotest[WILDCHAR]esm-basic[WILDCHAR]1.0.0[WILDCHAR]main.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import "npm:@denotest/esm-basic";
import { resolve } from "npm:@denotest/require-resolve";

console.log(resolve("@denotest/esm-basic", {
// when using the global cache, it should fallback to resolving bare
// specifiers with the global cache when it can't find it via the paths
paths: ["/home"],
}));
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports.resolve = (...args) => {
return require.resolve(...args);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "@denotest/require-resolve",
"version": "1.0.0",
"main": "index.cjs"
}

0 comments on commit 56bf634

Please sign in to comment.