Files
scriptc/tests/diagnostics/create-require.ts
Chris Tate 4abd8e4fff node:module compiles: createRequire's static erasure and the baked builtinModules
- createRequire(import.meta.url) (or __filename / import.meta.filename) in a const binding is compile-time plumbing that emits nothing; each require call through it resolves per site against the binding's own file, and the inline createRequire(import.meta.url)("spec") spelling erases identically
- The erasure per target: a builtin spec makes the binding a namespace import in const clothing (namespace, destructured, and inline-member spellings all key the existing module tables, with the fallback-typed 'as typeof import(...)' cast idiom stripped); a relative .json document validates at compile time and lowers to json.parse over its baked text (JSON.parse's checked-dynamic unknown stance — exactly Node's value); a bare name nothing installed resolves compiles to Node's catchable MODULE_NOT_FOUND throw (the optional-dependency try/require pattern); an installed npm package embeds under --dynamic through the island's NEW require-condition entry (NpmGraphBuilder.addRequire — a dual package answers its CJS arm, exactly Node's createRequire) and reports the requires-dynamic diagnostic in a static build
- Dynamic specifiers, '#' project imports, relative non-.json targets, --npm-static opt-ins, and non-this-file bases all fence by name; the island-handle rescue skips the plumbing decls so --dynamic builds erase them too
- module.builtinModules bakes as Node v24's exact list (a fresh string[] per read, pinned to the compat target so emitted programs stay host-independent); isBuiltin and syncBuiltinESMExports fence per site with pointed hints, and the createRequire hint, its diagnostics snapshot, the surface manifest, and the npm-static offender wording follow
- Corpus 2606 pins json/builtin/builtinModules/MODULE_NOT_FOUND differentially on both backends and under ASan; the npm create-require fixture case pins cjszoo's module.exports, dual's require-condition CJS arm, and the missing-package rejection against Node
2026-07-24 10:32:20 -05:00

24 lines
1009 B
TypeScript

// node:module — createRequire's LOWERED shape is a const binding over
// createRequire(import.meta.url) (or __filename) whose require calls
// take STATIC string literals (builtins, relative .json documents,
// installed npm packages under --dynamic). Everything else fences by
// name: a base that is not "this file" keeps the member fence (the
// returned require would resolve from a directory the compiler is not
// standing in), a computed specifier cannot exist in a fixed module
// graph, and a relative non-.json target is a program module — a
// static import.
import { createRequire } from "node:module";
// The base names some OTHER file: unrecognized — the member fence.
const req = createRequire("/tmp/parent.js");
console.log(String(req("./config.cjs")));
const require = createRequire(import.meta.url);
// A computed specifier: fenced by name.
const which = "left" + "-pad";
require(which);
// A relative non-.json target: program modules are static imports.
require("./helper.js");