mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-27 06:43:19 +08:00
Resolve bare core-module names to the builtin over npm packages
Node checks its builtins before node_modules for a bare core-module name, so an installed npm package named string_decoder (a transitive dependency of pi) never answers `import ... from "string_decoder"`. scriptc attributed the import to the package and refused it. The npm resolution now answers null for bare builtin names (prefix-only builtins such as node:test keep their bare names for packages), for ES imports and CommonJS requires alike. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
bcc35ddf1a
commit
98b3ced80c
@@ -3971,6 +3971,12 @@ function resolveNpmImport7(
|
||||
if (isRelativeSpecifier(specifier) || specifier.startsWith("node:")) {
|
||||
return null;
|
||||
}
|
||||
// Node resolves a bare core-module name (`string_decoder`, `events`,
|
||||
// `fs/promises`) to the builtin before it looks in node_modules, so an
|
||||
// installed npm package of the same name never answers it. Prefix-only
|
||||
// builtins (`node:test`) are listed with their prefix, so a bare `test`
|
||||
// still names the package.
|
||||
if (nodeBuiltinNames.has(specifier)) return null;
|
||||
// --provenance-sources: a registered specifier is NOT an npm import —
|
||||
// its attested source compiles as program modules (resolveProjectModule
|
||||
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/corpus/6235-bare-builtin-shadowed-package/helper.cjs",
|
||||
"<repo>/tests/corpus/6235-bare-builtin-shadowed-package/main.ts"
|
||||
],
|
||||
"diags": []
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// A CommonJS require of the bare names resolves to the builtins too.
|
||||
const { StringDecoder } = require("string_decoder");
|
||||
exports.decodeEuro = () => {
|
||||
const d = new StringDecoder("utf8");
|
||||
return d.write(Buffer.from([0xe2, 0x82])) + d.end(Buffer.from([0xac]));
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
// A bare core-module specifier names the Node builtin even when an npm
|
||||
// package of the same name is installed (pi depends on string_decoder
|
||||
// transitively): Node checks its builtins before node_modules.
|
||||
import { StringDecoder } from "string_decoder";
|
||||
import { EventEmitter } from "events";
|
||||
import { createRequire } from "node:module";
|
||||
|
||||
const decoder = new StringDecoder("utf8");
|
||||
console.log(decoder.write(Buffer.from([0xe2, 0x82])) + decoder.end(Buffer.from([0xac])));
|
||||
|
||||
const emitter = new EventEmitter();
|
||||
emitter.on("ping", (n: number) => console.log("ping", n));
|
||||
emitter.emit("ping", 1);
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
const helper = require("./helper.cjs") as { decodeEuro(): string };
|
||||
console.log("cjs", helper.decodeEuro());
|
||||
+1
@@ -0,0 +1 @@
|
||||
throw new Error("the npm events package was loaded");
|
||||
+1
@@ -0,0 +1 @@
|
||||
{ "name": "events", "version": "3.3.0", "main": "events.js" }
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
// An installed package named like the core module: Node never loads it
|
||||
// for the bare specifier.
|
||||
throw new Error("the npm string_decoder package was loaded");
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
{ "name": "string_decoder", "version": "1.3.0", "main": "index.js" }
|
||||
@@ -0,0 +1 @@
|
||||
{ "type": "module" }
|
||||
Reference in New Issue
Block a user