Repository navigation
Conversation
The project's "scriptc": { "packages": { name: "unloaded" } } map covered
require() and static imports of installed packages. Two shapes escaped it:
- A workspace package marked unloaded still resolved to its sources, so an
import() of it compiled the package and its whole dependency graph. The
workspace resolver now treats it as missing, and the import() rejects
with Node's ERR_MODULE_NOT_FOUND.
- A module only import() loads whose static import names a package Node
cannot resolve (unloaded or absent) failed the build with SC1010. Node
resolves that graph when the import() runs and rejects its promise
before any module of it evaluates. Preflight now walks each such root's
static graph; a refused graph becomes that rejection, with Node's
message and code, and its modules never join the compiled graph or the
npm selection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| const root = | ||
| resolveImport7(program, sf, arg.text) ?? npmStaticDepSf7(program, sf, arg.text); | ||
| if (root === null || root.isDeclarationFile || startup.has(root)) continue; | ||
| if (dynamicImportRejections.has(root) || covered.has(root)) continue; |
Contributor
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #1458.
Summary
A project marks packages it never loads in its package.json, as
"scriptc": { "packages": { "<name>": "unloaded" } }.require()and static imports of such a package fail with Node's MODULE_NOT_FOUND / ERR_MODULE_NOT_FOUND, exactly as when the package isn't installed, and the package never joins the program. Two shapes escaped that:import()of it compiled the package and its whole dependency graph. The workspace resolver now treats an unloaded name as missing. Theimport()rejects with Node'sERR_MODULE_NOT_FOUND("Cannot find package '' imported from ").import()loads, whose static import names a package Node can't resolve (unloaded or absent), failed the build with SC1010. Node resolves that module's static graph when theimport()runs, and rejects the promise before any module of the graph evaluates. Preflight now runs its existing resolution walk from each module reached only through a literalimport(). When the walk finds a refusal, thatimport()rejects with Node's message and code, and the refused graph's modules never join the compiled graph or the npm selection. The refusals inside that graph no longer fail the build.The rejection happens on a microtask after the call, as with any
import(). Code that reads the namespace afterawaitstill compiles, typed dynamically, because the namespace is never produced. Refusals in the startup graph keep their behavior: the program compiles to Node's startup crash.Evidence
New npm case
unloaded-dynamic-import. Both packages are missing under Node, which is the oracle:import()of an unloaded workspace package, with its namespace destructured;import()of a local module whose static import names an unloaded package.Each rejects with
ERR_MODULE_NOT_FOUNDand Node's message, and the local module's body never runs. Output is byte-identical to Node's.package-shims.test.tshas a new test that installs both packages: the workspace package linked intonode_modules, and an ES module package. Node loads both, which is the control. The compiled program's output is unchanged from the missing-package run.Before this change, the same program failed to build with SC1010, and an installed unloaded workspace package was compiled and run.
The existing
unloaded-optional-dependency,dynamic-import,dynamic-import-local,workspace-*andworkspace-dynamic-import-depsnpm cases pass. The npm, npm-static andpackage-shimssuites and the frontend unit tests pass 1106 of 1107; the one failure,node24-url-authority, comes from the sandbox's Node 24.15 versus the pinned 24.22.Zero-cost gate against Compile polyfill packages that are Node builtins as the builtins #1458's tip (8a40fb5, before its readable-stream 3.x commit, which this branch also carries): PASS. All 2502 programs (bench, self, corpus) are byte-identical; bench geomean is −0.18%.
The self-hosted compiler builds (identical in the gate), and
self-hosting-native-driver.test.tspasses (1155 s).pnpm lint,pnpm format:checkandtest:ts7 --baselines-onlypass. Re-recording all order baselines adds only the new cases' entries.🤖 Generated with Claude Code