Repository navigation
fix(routing): bundle CommonJS dependencies of compiled-binary API routes - #5477
kojiwakayama wants to merge 29 commits into
Conversation
A compiled binary cannot load a CommonJS file from disk at runtime, so the route build now bundles a project's CommonJS dependencies with esbuild's Node resolution and interop instead of loading them through a hand-written runtime CommonJS loader. ESM dependencies still load from file:// URLs. - built-ins a bundled module requires are imported statically and bound to the module-level require; any other id throws MODULE_NOT_FOUND - __dirname/__filename are defined per bundled CommonJS file - native addons fail the build with a clear message - bundled dependency files pass the same project boundary and import scan as route code Refs veryfront/veryfront-issue-inbox#4177, #5471
|
@codex review Posted by Claude Code (AI agent) on behalf of the PR author. |
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
📦 Client bundle boundary
A server module in a client graph aborts hydration in the browser. New leaks fail CI; known leaks are tracked in |
|
@codex review |
|
Score: 84/100. Replaces the runtime CJS loader in compiled binaries with esbuild bundling. The approach is sound, scoped to the compiled binary, and well tested.
I read the diff only and did not run the tests. Verify that CI passes, including the compiled-binary integration suite. Generated by Claude Code |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6f63222a64
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Files under the project's node_modules that a compiled-binary route bundles now resolve their own imports with esbuild's Node resolution (directory indexes, extensionless and .json requires) instead of the project's import map, @/ alias and adapter resolver, and are not held to the route-code import rules, which rejected ordinary package code such as computed property reads (mime-types, jsonwebtoken, semver). Elsewhere these dependencies load at runtime unscanned; they still load only from inside the project. Refs veryfront/veryfront-issue-inbox#4177
…nary routes The route build now bundles CommonJS dependencies, so the generated runtime loader (generateCompiledBinaryRequireShim), the require() rewrite of CommonJS dependency imports and its destructuring helper are unused. Remove them and their tests. Project-boundary symlink containment stays covered by the source snapshot tests. Move the esbuild bundling tests to tests/integration/semantic-unit-boundary, since they write temp files; the unit file keeps the pure helpers. Refs veryfront/veryfront-issue-inbox#4177
|
@codex review |
|
@codex review |
|
@codex review Posted by Claude Code (AI agent) on behalf of the PR author. |
|
Codex Review: Didn't find any major issues. Swish! Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
Wrap a CommonJS dependency in a function that passes __dirname and __filename, so a hashbang and a "use strict" prologue stay in effect and a file that declares one of them still reads the other. ESM dependency files (by extension, package type or syntax) are left alone. Resolve literal require.resolve() calls at build time, and serve runtime require()/require.resolve() for built-ins and for existing files inside the project; anything else throws MODULE_NOT_FOUND.
|
@codex review |
|
@codex review Posted by Claude Code (AI agent) on behalf of the PR author. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 22b529dd7d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
The Bun shard has no Deno global; use node:fs/promises instead.
|
@codex review Posted by Claude Code (AI agent) on behalf of the PR author. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a41c0b042b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Bun defines __dirname and __filename in ESM modules too.
|
@codex review Posted by Claude Code (AI agent) on behalf of the PR author. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 52d7ee7db3
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…e does
Parse each CommonJS dependency file with the bundler instead of matching
its text: ESM syntax comes from the parser, and unbound __dirname,
__filename and require.resolve("literal") are replaced through define.
No wrapper function is added, so arguments, the hashbang and the
directive prologue are untouched.
Inside dependencies, resolve extensionless relative imports in Node's
order (.js, .json, .node), read only the main field, and stop the
package-type lookup at node_modules. Workspace packages linked from
node_modules count as dependencies. Prefix-only built-ins such as
"test" no longer resolve without the node: prefix.
…iles Bundled dependency files now run through the runtime require's cache: cached before the body runs, evicted on throw or on deletion. Top-level arguments carry Node's five wrapper values. Forced CommonJS files with ES module syntax throw a SyntaxError. The build reads module-sync. The runtime require strips TypeScript types, reads BOM-prefixed and rejects malformed package scopes, accepts pkg/ root ids, evicts unreadable files, and resolves import.meta.resolve packages with import conditions. Windows backslash require ids resolve at build time, and package target suffixes are kept.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3d4664b5d0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…me has it Bun has no stripTypeScriptTypes; there the runtime require refuses the file with ERR_UNKNOWN_FILE_EXTENSION instead of running it.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 34e7bf1438
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…endencies - A dependency that assigns require, plainly or compoundly, gets its own binding. - Files with extensions Node has no loader for are prepared as CommonJS. - #imports stop at node_modules; a package resolves its own name first. - import.meta.resolve returns package-map targets that do not exist yet. - require.resolve keeps Node's paths API, require.resolve.paths and module.paths. - An ES module JSON import with type json stays apart from require()'s module. - ES module dependencies see no require binding. - Generated code writes paths through codeString.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2706f75bec
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…ort.meta - A malformed package scope fails every id resolved from it, as Node's self-reference lookup does, and import.meta.resolve reports it. - JSON a computed require loads first gets a complete module record. - Modules record their parent and children. - require.resolve with paths resolves absolute, #imports and self ids from the caller first. - A linked workspace lookup stops at the copy that refuses an id. - A type json import shares require()'s module unless it has a query. - An ES module's require is undeclared, so assigning it throws. - import.meta has a null prototype and main: false; file URLs with a host are rejected on POSIX.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c006f1c5e1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…bad packages - A bundled module's computed requires use its own require, so a call it makes after its body ran still names it as the parent. - A failed load leaves its parent's children as well as the cache. - A malformed package.json of a required package or directory throws ERR_INVALID_PACKAGE_CONFIG instead of MODULE_NOT_FOUND. - Direct eval is detected from the parsed output, so (eval)(x) and commented spellings count.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a652bd135
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
…ir dependency
- A literal require in a bundled CommonJS dependency is marked as the
module's own, so one a callback makes after the body has finished still
names that module as its parent and child.
- require() and require.resolve() reject a non-string id with Node's
TypeError ERR_INVALID_ARG_TYPE, and require('') with
ERR_INVALID_ARG_VALUE, instead of MODULE_NOT_FOUND.
- An import() the bundler cannot follow resolves from the dependency file,
as import.meta.resolve there would; one that does not resolve rejects.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a079aa73f
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (onlyHelperCalls(code, BUNDLED_REQUIRE_FROM)) { | ||
| code = code.replace(new RegExp(`\\b${BUNDLED_REQUIRE_FROM}\\b`, "g"), requireFrom); |
There was a problem hiding this comment.
Avoid rewriting helper-shaped text in strings
When route code contains the exact text __vf_require_from("..., for example inside a tagged template such as String.raw\__vf_require_from("x")`, onlyHelperCalls()` counts that textual occurrence as a generated call. This fast path then replaces the identifier globally, including inside the template, so the compiled route exports different string data than the source supplied. Use the parser-based free-reference rewrite for this case as well, or make the fast-path detection syntax-aware rather than matching raw text.
Useful? React with 👍 / 👎.
| try { | ||
| // The bundler names files relative to its working directory, with | ||
| // symlinks followed; this keys them the way computed requires do. | ||
| const path = host.realpathSync(host.join(bundleRoot!, key)); |
There was a problem hiding this comment.
Map suffixed CommonJS imports to their real cache path
When the same CommonJS file is imported with a query or fragment, esbuild includes that suffix in the generated CommonJS module key, so passing the key directly to realpathSync looks for a nonexistent filename such as a.cjs?x. bundledPath() then returns null and leaves each suffixed import in esbuild's separate helper cache instead of the shared runtime cache; Node 24.15 ignores the suffix for the underlying CommonJS load, so import "./a.cjs?x", import "./a.cjs?y", and require("./a.cjs") all evaluate once and return the same exports object. Recover the suffix-free filesystem path before cache lookup so state and object identity do not depend on the import spelling.
AGENTS.md reference: AGENTS.md:L20-L22
Useful? React with 👍 / 👎.
| return BUILTINS.has(specifier) ? specifier : undefined; | ||
| } | ||
|
|
||
| const NATIVE_ADDON = /\.node$/i; |
There was a problem hiding this comment.
Keep Node extension matching case-sensitive
On case-sensitive hosts, Node treats an explicitly required file such as entry.NODE as an unknown extension and runs it through the CommonJS JavaScript loader, but this case-insensitive pattern classifies it as a native addon and rejects the build. The same case folding appears in the runtime .node/.mjs/.mts checks, so uppercase extensions can also receive ERR_DLOPEN_FAILED or ERR_REQUIRE_ESM instead of executing as CommonJS. Match Node's exact lowercase loader extensions on POSIX rather than applying /i across these sibling paths.
AGENTS.md reference: AGENTS.md:L23-L25
Useful? React with 👍 / 👎.
| return url.href; | ||
| }; | ||
| return (specifier) => { | ||
| const id = String(specifier); |
There was a problem hiding this comment.
Reject Symbol module specifiers during string coercion
When a bundled dependency calls detached import.meta.resolve(Symbol("x")) or import(Symbol("x")), String(specifier) converts the symbol to the package-like text Symbol(x) and the helper reports ERR_MODULE_NOT_FOUND. Native Node uses the ECMAScript abstract string conversion for module specifiers, which rejects symbols with a TypeError; code can therefore misclassify this programming error as an absent optional package. Perform specifier coercion with the same Symbol-rejecting semantics as the native APIs.
Useful? React with 👍 / 👎.
The runtime require() and import.meta.resolve() of a bundled dependency now throw what Node 24 throws instead of a generic MODULE_NOT_FOUND: ERR_PACKAGE_PATH_NOT_EXPORTED for a subpath exports does not define, ERR_PACKAGE_IMPORT_NOT_DEFINED for an undefined #import, ERR_INVALID_PACKAGE_CONFIG for exports mixing subpaths and conditions, and ERR_INVALID_PACKAGE_TARGET for a target that leaves its package. Optional-dependency code that catches MODULE_NOT_FOUND no longer hides a broken package.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0a2a12cfe3
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const jsExtension = /\.(?:jsx?|ts)$/i.test(filePath); | ||
| // Node's require() loads a file without an extension, or with one it has | ||
| // no loader for, as CommonJS, whatever its package declares; a package | ||
| // `main` may name one. | ||
| const extensionless = !KNOWN_EXTENSION.test(filePath); | ||
| if (!cjsExtension && !extensionless && !(jsExtension && packageType !== "module")) return null; |
There was a problem hiding this comment.
Treat JSX extensions as unknown CommonJS files
When a dependency explicitly requires a lowercase .jsx or .tsx file, Node treats that extension as unknown and executes the file as CommonJS even inside a "type": "module" package. Including jsx here makes .jsx follow the package type, while the sibling KNOWN_EXTENSION pattern makes .tsx skip the unknown-extension path entirely. As a result, CommonJS bindings such as __dirname are not prepared, and TypeScript syntax in .tsx is transpiled successfully where Node throws a SyntaxError. Keep both extensions on the unknown-extension CommonJS path.
AGENTS.md reference: AGENTS.md:L23-L25
Useful? React with 👍 / 👎.
| for (const entry of [...computed].sort((a, b) => b.s - a.s)) { | ||
| result = result.slice(0, entry.s) + `${marker}(${result.slice(entry.s, entry.e)})` + | ||
| result.slice(entry.e); |
There was a problem hiding this comment.
Keep computed CommonJS imports inside the bundled loader
When a delayed computed import(id) resolves to a CommonJS .js or .cjs dependency, this rewrite feeds its file URL to the native import() rather than the bundle's CommonJS runtime. In a compiled Deno binary that bypasses the shared cache and attempts to load the CommonJS file from disk, which is precisely the unsupported path this change is intended to replace and can evaluate it as ESM or fail. The new integration coverage exercises only plugin.mjs and a type: module package, so it misses this distinct target type; computed imports resolving to CommonJS must return the bundled module's namespace instead.
AGENTS.md reference: AGENTS.md:L26-L28
Useful? React with 👍 / 👎.
|
|
Replaced by #5484. It loads CommonJS dependencies through the runtime's own createRequire, which works in Deno 2.9 compiled binaries, instead of a custom loader. The open review threads here no longer apply. |



Summary
In a compiled binary, API routes now bundle the project's CommonJS dependencies with esbuild. Before, a hand-written runtime CommonJS loader loaded them, and this PR removes that loader.
deno compilebinaries cannot load a CommonJS file from disk at runtime:requirethere reads only embedded files, and importing a.cjsfile evaluates it as ESM. Bundling gives Node's resolution and interop from esbuild. ESM dependencies still load fromfile://URLs.This replaces the approach in #5472, which is closed unmerged.
requirethat bundled code calls at runtime serves any built-in throughprocess.getBuiltinModule, including a computed id. Any other package id throwsMODULE_NOT_FOUND, so optional dependencies probed intrystill fall back.__dirname,__filenameorrequire.resolveis parsed once by the bundler, not matched as text. In a CommonJS file, unbound__dirnameand__filenamebecome constants, and eachrequire.resolve("literal")becomes the path Node returns. No wrapper is added, soarguments, a hashbang and a"use strict"prologue are unchanged. An extensionless file, which Node'srequire()loads as CommonJS, gets the same treatment. A.jsfile counts as ESM by its packagetype(looked up no further thannode_modules, as in Node) or by the parser's verdict on its syntax.import.meta.url(with the query it was imported with),filenameanddirnamepoint at the file itself, andimport.meta.resolve("literal")resolves at build time. A computed or detachedimport.meta.resolvecalls a resolver bound to the file. That resolver looks up a package name or#importthrough the runtimerequirewith theimportcondition and keeps a target's query.requirefinds a file in Node's order: the path, then with.js,.jsonor.node, then the directory's package.jsonmain, then itsindex. JSON loads from anywhere in the project, with a byte order mark dropped, and so does a package.json. A JavaScript file loads only from the project's dependencies, as CommonJS with its ownrequireand Node'smoduleobject, sorequire(path.join(__dirname, "dialects", name + ".js"))works. A package name is looked up innode_modulesfrom the requiring file upwards (from the project root for route code), throughexports(including*patterns,nullblocks, array fallbacks past invalid targets, percent-escaped targets with any query or fragment dropped; targets cannot leave the package, and a map mixing subpath and condition keys is refused) ormain. On Windows,.\\and..\\ids are relative. The nearest copy of a package that refuses the path ends the lookup, as in Node. A#namegoes through the package'simports.require.resolvereturns the real path and takes Node'spathsoption. A native addon throwsERR_DLOPEN_FAILED, and an ES module (.mjs, or.jsor.tsin atype: modulepackage) throwsERR_REQUIRE_ESM. A.tsor.ctsfile runs with its types stripped, as in Node 24. A malformed package scope throwsERR_INVALID_PACKAGE_CONFIG, andpkg/loads the package root. Project JavaScript never loads this way. Bare prefix-only names such astestare not built-ins.requirethe bundler leaves in a bundled dependency file, such as a computed id, runs with the runtimerequireof that file's directory, as in Node. A file that uses directevaldeclaresrequire,__dirnameand__filenamefor its own directory.require's module cache, as Node's one cache. The route prologue routes esbuild's__commonJShelper through it. A module is cached before its body runs, so a cycle through a computedrequiresees it partly loaded. It leaves the cache if its body throws, and a computed and a literalrequireof one file share it either way round.require.cacheexposes it, and deleting an entry makes the next load, literal or computed, run the file again. An unknown helper shape fails the build.argumentsholds Node's five wrapper values. A file Node parses as CommonJS (.cjs,.cts, or"type": "commonjs") that has ES module syntax throws aSyntaxErrorwhen it runs. A file with an extension Node has no loader for runs as CommonJS, even in a"type": "module"scope. A file that reassignsrequire, plainly or with a compound assignment, gets its own binding. A dependency ES module has norequirebinding.requirefollows Node's package rules: a package's own name resolves through itsexportsbeforenode_modules,#importsstop atnode_modules, andrequire.resolvekeeps thepathsoption (relative entries resolve from the working directory, invalid values throw),require.resolve.paths()andmodule.paths.import.meta.resolvereturns a package-map target that does not exist yet.with { type: "json" }import of a dependency's JSON gets the modulerequire()caches, as in Node 24; one with a query or fragment is a JSON module of its own.onLoadcallbacks now receive the import attributes (OnLoadArgs.with).parentandchildren, each bundled module has its ownrequire, and a failed load leaves both the cache and its parent'schildren. A malformed package.json of a required package or directory throwsERR_INVALID_PACKAGE_CONFIG. Direct eval is recognized in every spelling. Also, and JSON a computedrequireloads first gets a complete module record. A malformed package scope fails every id resolved from it withERR_INVALID_PACKAGE_CONFIG,import.meta.resolveincluded. Withpaths, absolute,#importand self ids resolve from the caller first. A linked workspace package's lookup stops at the copy that refuses an id.import.metahas a null prototype andmain: false; a POSIX file URL with a host throwsERR_INVALID_FILE_URL_HOST; assigningrequirein an ES module throws aReferenceError..ctsfiles are CommonJS TypeScript, and.jsxand.tsfiles are prepared like.js.@/alias or a relativenode_modulespath is prepared as a dependency.@scopedirectory counts as a dependency directory.veryfront) apply only to parsed import specifiers. Package strings that read like imports stay as written..nodefiles) fail the build with a clear message that names only the file. A package whose name ends in.nodestill bundles.importandimport(), and only where it resolves to the project's own copy; a dependency's nested copy is bundled for it. A dependency's import of a subpath names the file the package'sexportsmap it to. Arequire()of it from a bundled dependency bundles its CommonJS export, so a dual package works from both sides.nodeandmodule-syncconditions andmain, nevermodule.node-addonsstays off, as under--no-addons, since the binary cannot load addons. Extensionless relative imports try.js,.json,.node, then the directory'sindex, rather than a TypeScript or.mjssibling. The project's import map and@/alias don't apply. Workspace packages linked fromnode_modulesto a directory inside the project count as dependencies.mime-types,jsonwebtokenandsemver. Dependency files still load only from inside the project.generateCompiledBinaryRequireShim, therequire()rewrite of CommonJS dependency imports, and the destructuring helper it used, plus their tests. Symlink containment stays covered by the source snapshot tests.Only the compiled binary changes. Deno source runs, Node and Bun are unchanged.
Behaviour changes in the compiled binary
app/api/x/route.ts:1:16: Could not resolve "pg"). It no longer fails at runtime.paths, as in Node.module.parentis the module that first required a dependency, as in Node, and undefined for one the route imports.createRequirefromnode:modulein a dependency is the runtime's own, with a cache apart from the bundle's.Not in this PR
Hosted runtimes still do not install tenant
package.jsondependencies. That is separate work.Test plan
compiled-cjs-bundling.test.ts(unit) covers built-in names, the package-type lookup stopping atnode_modules, Node's extension order, prefix-only built-in ids, and helper naming.tests/integration/semantic-unit-boundary/.../compiled-cjs-bundling.test.tsbundles and imports real packages. It covers anexportsmap, built-in/JSON/optional requires,__dirname, and a route-levelrequirebinding. It also coversrequire.resolve(relative, self, built-in, missing), a computed runtimerequireof in-project JSON, rejection of a path outside the project, ESM dependencies getting no CommonJS bindings, and rejection of a native addon. Newer cases cover:require.resolveorexport;argumentsin a CommonJS file;.mjsbeside.json,.tsbeside.js, a module-only package);requirebinding with nothing bundled;require;require;main, and an extensionlessmainor defaultindexbeside a.tssibling;import.meta(computed, detached, built-in and bare);client.node;paths;import.meta.url;requirein a bundled dependency;import.meta.resolveof a package's own#import;exportsremap;eval;require,require.cachedeletion with a literal re-require, and a top-levelreturn;arguments,module-sync, forced CommonJS syntax, runtime TypeScript and a BOM-prefixed package scope;require, an unknown-extensionmainin a module scope, package self-reference,#importsscope ending atnode_modules,require.resolvepaths, a not-yet-built#importtarget, a JSON import attribute, andtypeof requirein an ES module;parent,children), a complete JSON cache entry, a malformed package scope, caller-scoped ids withpaths,import.meta's shape, file URL hosts,requireassignment in an ES module, and a linked workspace package whose nearest copy refuses an id;requirefrom a bundled module, failed loads, malformed target packages and directories, and(eval)(x).Each new case was checked to fail with its fix reverted.
/app-style project, nonode_modules,VERYFRONT_HOST_ALLOW_PROJECT_EXECUTION=1,serve --mode=production.node:crypto,node:pathand a relative TS module returned 200 in 0.03 s.pgfailed closed withCould not resolve "pg". On main this route failed on the first request with MODULE_NOT_FOUND.bin/veryfrontlocally and ranserve --mode=production:requireoffsreturned 200 (rebuilt on d0532c2).require(path.join(__dirname, ...))returned 200, and its exported'from "fs"'string came back unchanged.pg,jsonwebtoken,lodash,mime-typesandsemver(1,253.jsfiles innode_modules) returned 200. The cold build took 0.11–0.15 s, against 0.11 s before the parse and resolution changes; warm requests take 5 ms.@/node_modules/..., and declaring its own__vf_require_from, returned 200 with one shared module (rebuilt on dd15aac).requireof a.ctsfile, top-levelarguments, and arequire.cachedeletion and re-require returned 200. The values matched Node's (types stripped, five arguments, the file ran again). The real-package route cold-built in 0.12 s.require, a.foomain with five arguments,MODULE_NOT_FOUNDfor a scope-less#config, a separate JSON import object,typeof require"undefined" in ESM, and the not-yet-built target URL. All other routes still returned 200.children["a.js","b.js","d.json"], a complete JSON cache entry,import.metawith a null prototype andmain: false,ERR_INVALID_FILE_URL_HOSTand aReferenceErrorfor an ES modulerequireassignment. All other routes still returned 200.require, a failed load, malformed packages and(eval)("require")returned Node's values, and all other routes still returned 200.deno task test:fileon the loader, rewriter, loader-helpers, import-rewriter core and new tests: all pass. The semantic test audit passes.Closes #5471.
Posted by Claude Code (AI agent) on behalf of the PR author.