Compare commits

...

2 Commits

Author SHA1 Message Date
Claude Bot
d80f5fc703 Address review comments: use URL API and static import
- Use new URL(import.meta.url).pathname to parse the URL and check for
  /$bunfs/ in the pathname instead of checking the raw URL string
- Remove Windows-specific B:\\~BUN\\ check as URL pathname normalization
  handles platform differences
- Move pathToFileURL import to module-level static import instead of
  dynamic import inside the plugin handler

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 06:19:32 +00:00
Claude Bot
7ab2b36495 test(bundler): add regression test for plugin transform import.meta.url
Add a regression test for GitHub issue #26653 which reported that
transitive dependencies could incorrectly use real filesystem paths
instead of virtual /$bunfs/ paths in standalone builds when a plugin
transforms files.

The test verifies that when a plugin's onLoad callback transforms a
file, the transitive dependencies (files imported by the transformed
file) still correctly have import.meta.url pointing to the virtual
filesystem path rather than the original filesystem path.

Testing shows the basic behavior is correct - this test ensures it
stays that way. The original issue may only manifest in very large
codebases (70+ transformed files).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 06:05:45 +00:00

View File

@@ -3,6 +3,7 @@ import { describe, expect, test } from "bun:test";
import { rmSync } from "fs";
import { bunEnv, bunExe, isWindows, tempDir, tempDirWithFiles } from "harness";
import { join } from "path";
import { pathToFileURL } from "url";
import { itBundled } from "./expectBundled";
describe("bundler", () => {
@@ -935,4 +936,65 @@ const server = serve({
const result = await Bun.$`./app`.cwd(dir).env(bunEnv).nothrow();
expect(result.stdout.toString().trim()).toBe("IT WORKS");
});
// Regression test for https://github.com/oven-sh/bun/issues/26653
// When a plugin transforms a file's content, transitive dependencies should
// still have correct import.meta.url pointing to the virtual /$bunfs/ path,
// not the original filesystem path.
itBundled("compile/PluginTransformPreservesTransitiveImportMetaUrl", {
compile: true,
backend: "api",
outfile: "dist/out",
files: {
"/entry.ts": /* js */ `
import { processData } from "./model.ts";
const result = processData();
console.log("Result:", result);
`,
"/model.ts": /* js */ `
// This file is transformed by a plugin - it uses a placeholder
// that gets replaced with the actual filesystem path
import { helper } from "./utils.ts";
const MODEL_URL = "MODEL_URL_PLACEHOLDER";
export function processData() {
console.log("Model URL:", MODEL_URL);
return helper();
}
`,
"/utils.ts": /* js */ `
// This transitive dependency is NOT transformed by the plugin.
// Its import.meta.url should point to the virtual /$bunfs/ path,
// not the original filesystem path.
export function helper() {
const url = import.meta.url;
console.log("Utils URL:", url);
// Verify the URL is the virtual path by parsing it with URL API
const pathname = new URL(url).pathname;
if (pathname.includes("/$bunfs/")) {
return "success";
} else {
return "FAIL: import.meta.url pathname is not virtual path: " + pathname;
}
}
`,
},
plugins: [
{
name: "transform-model",
setup(api) {
api.onLoad({ filter: /model\.ts$/ }, async args => {
const contents = await Bun.file(args.path).text();
// Replace placeholder with actual filesystem path
const fileUrl = pathToFileURL(args.path).href;
const transformed = contents.replace("MODEL_URL_PLACEHOLDER", fileUrl);
return { contents: transformed, loader: "ts" };
});
},
},
],
run: {
// The output should show success from utils.ts, verifying import.meta.url is correct
stdout: /Result: success/,
},
});
});