Compare commits

...

1 Commits

Author SHA1 Message Date
Claude Bot
6a506d78b5 fix(bundler): preserve original specifier in require.resolve() output
When bundling, `require.resolve('pkg/path')` was being rewritten to use
the resolved absolute path from the build machine (e.g.,
`require.resolve("/home/user/project/node_modules/pkg/path")`). This
caused failures when running `bun build --compile` binaries on different
machines, since the hardcoded absolute path doesn't exist there.

Now uses the `original_path` field (which preserves the original import
specifier) instead of the resolved `path.text` when printing
`require.resolve()` calls.

Closes #27530

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-27 20:04:17 +00:00
2 changed files with 38 additions and 1 deletions

View File

@@ -2383,7 +2383,16 @@ fn NewPrinter(
}
p.print("(");
p.printStringLiteralUTF8(p.importRecord(e.import_record_index).path.text, true);
const record = p.importRecord(e.import_record_index);
// Use the original specifier if available, so that require.resolve()
// calls are resolved at runtime rather than being hardcoded to
// an absolute path from the build machine. This is critical for
// `bun build --compile` where the binary runs on different machines.
const path_to_print = if (record.original_path.len > 0)
record.original_path
else
record.path.text;
p.printStringLiteralUTF8(path_to_print, true);
p.print(")");
if (wrap) {

View File

@@ -3991,6 +3991,34 @@ describe("bundler", () => {
},
external: ["external-pkg", "@scope/external-pkg", "{{root}}/external-file"],
});
// https://github.com/oven-sh/bun/issues/27530
itBundled("default/RequireResolvePreservesOriginalSpecifier", {
files: {
"/entry.js": /* js */ `
console.log(require.resolve('my-pkg/package.json'))
console.log(require.resolve('my-pkg'))
console.log(require.resolve('@scope/my-pkg/subpath'))
`,
"/node_modules/my-pkg/package.json": JSON.stringify({ name: "my-pkg", version: "1.0.0", main: "index.js" }),
"/node_modules/my-pkg/index.js": `module.exports = {}`,
"/node_modules/@scope/my-pkg/package.json": JSON.stringify({
name: "@scope/my-pkg",
version: "1.0.0",
main: "index.js",
}),
"/node_modules/@scope/my-pkg/index.js": `module.exports = {}`,
"/node_modules/@scope/my-pkg/subpath.js": `module.exports = {}`,
},
target: "bun",
onAfterBundle(api) {
// require.resolve() should preserve the original specifier, not an absolute path
api.expectFile("/out.js").toContain('require.resolve("my-pkg/package.json")');
api.expectFile("/out.js").toContain('require.resolve("my-pkg")');
api.expectFile("/out.js").toContain('require.resolve("@scope/my-pkg/subpath")');
// Must not contain absolute paths from the build machine
api.expectFile("/out.js").not.toMatch(/require\.resolve\("\/[^"]*node_modules/);
},
});
itBundled("default/InjectMissing", {
files: {
"/entry.js": ``,