Skip to content

fix(ext/node): resolve global cache packages when require referrer is outside DENODIR#34497

Merged
littledivy merged 2 commits into
mainfrom
orch/divybot-276
May 30, 2026
Merged

fix(ext/node): resolve global cache packages when require referrer is outside DENODIR#34497
littledivy merged 2 commits into
mainfrom
orch/divybot-276

Conversation

@divybot

@divybot divybot commented May 29, 2026

Copy link
Copy Markdown
Contributor

Summary

In global-cache mode (--no-node-modules-dir), a CJS require() whose
referrer module lives outside of DENODIR could not resolve top-level
npm dependencies by bare specifier. The managed npm folder resolver
requires the referrer to be inside the cache so it can anchor the
lookup; when it isn't, the request fell through to a fruitless
node_modules ancestor walk and threw Cannot find module.

This is the Playwright config-transpile scenario described in
#25189: Playwright lives in the global cache, installs a require()
hook, transpiles the user's playwright.config.js to CJS, and then
re-issues require("playwright/test") with the user's config file as
the parent module. The user's config file is not in the cache, so
resolve_package_folder_from_package bails out with
ReferrerNotFoundError, no global-cache path is added to
Module._resolveLookupPaths, and the lookup fails.

What this does

op_require_resolve_deno_dir now falls back, when the referrer-based
resolution fails and the referrer is not inside an npm package, to
looking up the bare specifier's package name as a top-level dependency
in the npm graph. The new NodeRequireLoader::resolve_package_folder_from_name
trait method lets the CLI plug in the actual resolution; the default
returns None, and the CLI implementation only resolves in managed +
global-cache mode (byonm and local node_modules are unaffected
because they already handle this case via the ancestor node_modules
walk).

This is also consistent with the JS-side fallback at
Module._resolveFilename that fires when options.paths is provided
and exercised by the existing
tests/specs/npm/require_resolve_bad_paths_global_cache test —
that fallback resolves the same way through the global cache, just for
a different trigger.

Fixes #25189.

Closes denoland/orchid#276

Test plan

  • cargo check --bin deno passes
  • cargo fmt --check / rustfmt --check passes
  • CI runs the new tests/specs/npm/require_resolve_outside_cache spec
  • CI passes

divybot and others added 2 commits May 29, 2026 06:56
… outside DENODIR

Closes denoland/orchid#276

In global-cache mode (`--no-node-modules-dir`), a CJS `require()` whose
referrer module lives outside of DENODIR could not resolve top-level npm
dependencies by bare specifier. The npm folder resolver requires the
referrer to be inside the cache so it can anchor the lookup, and when it
isn't (for example, a transpiled user-project file invoked from a
require-hook installed by a cached package) the request would fall
through to a fruitless `node_modules` walk and throw
`Cannot find module`.

This is the Playwright config-transpile scenario from
#25189: Playwright lives in the
global cache, installs a `require()` hook, transpiles the user's
`playwright.config.js` to CJS, and then re-issues
`require("playwright/test")` with the user's config file as the parent
module.

`op_require_resolve_deno_dir` now falls back, when the referrer-based
resolution fails and the referrer is not inside an npm package, to
looking up the bare specifier's package name as a top-level dependency
in the managed npm graph. A new `NodeRequireLoader` trait method,
`resolve_package_folder_from_name`, lets the CLI plug in the actual
resolution; the default returns `None`, and the byonm/local node_modules
paths are unaffected because they already handle this case via the
ancestor `node_modules` walk.

Co-Authored-By: Divy Srivastava <[email protected]>

@littledivy littledivy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@littledivy
littledivy merged commit 5c9fb8e into main May 30, 2026
136 checks passed
@littledivy
littledivy deleted the orch/divybot-276 branch May 30, 2026 06:37
littledivy pushed a commit to crowlKats/deno that referenced this pull request Jun 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

require doesn't resolve in the global cache dir if referrer is not in DENODIR

2 participants