summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2024-04-30 23:41:29 -0400
committerGitHub <noreply@github.com>2024-04-30 23:41:29 -0400
commit56bf634fa9721832b605dd91ced5329e0329a8f8 (patch)
tree15595d6beca6d712ad502c830c42fe533c25c237
parent486437fee1ac53610a901b07bda91909844ec9ab (diff)
fix(node): require.resolve - fallback to global cache when bare specifier 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)
-rw-r--r--ext/node/polyfills/01_require.js33
-rw-r--r--tests/specs/npm/require_resolve_bad_paths_global_cache/__test__.jsonc4
-rw-r--r--tests/specs/npm/require_resolve_bad_paths_global_cache/main.out9
-rw-r--r--tests/specs/npm/require_resolve_bad_paths_global_cache/main.ts8
-rw-r--r--tests/testdata/npm/registry/@denotest/require-resolve/1.0.0/index.cjs3
-rw-r--r--tests/testdata/npm/registry/@denotest/require-resolve/1.0.0/package.json5
6 files changed, 54 insertions, 8 deletions
diff --git a/ext/node/polyfills/01_require.js b/ext/node/polyfills/01_require.js
index 27c10bf58..efde1eb79 100644
--- a/ext/node/polyfills/01_require.js
+++ b/ext/node/polyfills/01_require.js
@@ -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.");
@@ -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) {
@@ -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;
@@ -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;
};
diff --git a/tests/specs/npm/require_resolve_bad_paths_global_cache/__test__.jsonc b/tests/specs/npm/require_resolve_bad_paths_global_cache/__test__.jsonc
new file mode 100644
index 000000000..70840dee2
--- /dev/null
+++ b/tests/specs/npm/require_resolve_bad_paths_global_cache/__test__.jsonc
@@ -0,0 +1,4 @@
+{
+ "args": "run --allow-read main.ts",
+ "output": "main.out"
+}
diff --git a/tests/specs/npm/require_resolve_bad_paths_global_cache/main.out b/tests/specs/npm/require_resolve_bad_paths_global_cache/main.out
new file mode 100644
index 000000000..563d84ac4
--- /dev/null
+++ b/tests/specs/npm/require_resolve_bad_paths_global_cache/main.out
@@ -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
diff --git a/tests/specs/npm/require_resolve_bad_paths_global_cache/main.ts b/tests/specs/npm/require_resolve_bad_paths_global_cache/main.ts
new file mode 100644
index 000000000..c3b236c8f
--- /dev/null
+++ b/tests/specs/npm/require_resolve_bad_paths_global_cache/main.ts
@@ -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"],
+}));
diff --git a/tests/testdata/npm/registry/@denotest/require-resolve/1.0.0/index.cjs b/tests/testdata/npm/registry/@denotest/require-resolve/1.0.0/index.cjs
new file mode 100644
index 000000000..b76925077
--- /dev/null
+++ b/tests/testdata/npm/registry/@denotest/require-resolve/1.0.0/index.cjs
@@ -0,0 +1,3 @@
+exports.resolve = (...args) => {
+ return require.resolve(...args);
+};
diff --git a/tests/testdata/npm/registry/@denotest/require-resolve/1.0.0/package.json b/tests/testdata/npm/registry/@denotest/require-resolve/1.0.0/package.json
new file mode 100644
index 000000000..03631e993
--- /dev/null
+++ b/tests/testdata/npm/registry/@denotest/require-resolve/1.0.0/package.json
@@ -0,0 +1,5 @@
+{
+ "name": "@denotest/require-resolve",
+ "version": "1.0.0",
+ "main": "index.cjs"
+ }