mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
Fix crash in bundler related to onLoad plugins that return file loader for HTML imports (#20849)
This commit is contained in:
@@ -34,10 +34,6 @@ emit_decorator_metadata: bool = false,
|
||||
ctx: *BundleV2,
|
||||
package_version: string = "",
|
||||
is_entry_point: bool = false,
|
||||
/// This is set when the file is an entrypoint, and it has an onLoad plugin.
|
||||
/// In this case we want to defer adding this to additional_files until after
|
||||
/// the onLoad plugin has finished.
|
||||
defer_copy_for_bundling: bool = false,
|
||||
|
||||
const ParseTaskStage = union(enum) {
|
||||
needs_source_code: void,
|
||||
|
||||
@@ -1964,7 +1964,8 @@ pub const BundleV2 = struct {
|
||||
this.decrementScanCounter();
|
||||
},
|
||||
.success => |code| {
|
||||
const should_copy_for_bundling = load.parse_task.defer_copy_for_bundling and code.loader.shouldCopyForBundling();
|
||||
// When a plugin returns a file loader, we always need to populate additional_files
|
||||
const should_copy_for_bundling = code.loader.shouldCopyForBundling();
|
||||
if (should_copy_for_bundling) {
|
||||
const source_index = load.source_index;
|
||||
var additional_files: *BabyList(AdditionalFile) = &this.graph.input_files.items(.additional_files)[source_index.get()];
|
||||
@@ -2619,9 +2620,6 @@ pub const BundleV2 = struct {
|
||||
pub fn enqueueOnLoadPluginIfNeededImpl(this: *BundleV2, parse: *ParseTask) bool {
|
||||
if (this.plugins) |plugins| {
|
||||
if (plugins.hasAnyMatches(&parse.path, true)) {
|
||||
if (parse.is_entry_point and parse.loader != null and parse.loader.?.shouldCopyForBundling()) {
|
||||
parse.defer_copy_for_bundling = true;
|
||||
}
|
||||
// This is where onLoad plugins are enqueued
|
||||
debug("enqueue onLoad: {s}:{s}", .{
|
||||
parse.path.namespace,
|
||||
|
||||
@@ -820,4 +820,80 @@ describe("bundler", () => {
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
itBundled("plugin/FileLoaderWithCustomContents", {
|
||||
files: {
|
||||
"index.html": /* html */ `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test</title>
|
||||
</head>
|
||||
<body>
|
||||
<img src="./image.jpeg" />
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
`,
|
||||
"script.js": /* js */ `
|
||||
console.log("Script loaded");
|
||||
`,
|
||||
"image.jpeg": "actual image data would be here",
|
||||
},
|
||||
entryPoints: ["./index.html"],
|
||||
outdir: "/out",
|
||||
plugins(build) {
|
||||
// This plugin intercepts .jpeg files and returns them with custom contents
|
||||
// This previously caused a crash because additional_files wasn't populated
|
||||
build.onLoad({ filter: /\.jpe?g$/ }, async args => {
|
||||
return {
|
||||
loader: "file",
|
||||
contents: "custom image contents",
|
||||
};
|
||||
});
|
||||
},
|
||||
onAfterBundle(api) {
|
||||
// Verify the build succeeded and files were created
|
||||
api.assertFileExists("index.html");
|
||||
// The image should be copied with a hashed name
|
||||
const html = api.readFile("index.html");
|
||||
expect(html).toContain('src="');
|
||||
expect(html).toContain('.jpeg"');
|
||||
},
|
||||
});
|
||||
|
||||
itBundled("plugin/FileLoaderMultipleAssets", {
|
||||
files: {
|
||||
"index.js": /* js */ `
|
||||
import imgUrl from "./image.png";
|
||||
import wasmUrl from "./module.wasm";
|
||||
console.log(imgUrl, wasmUrl);
|
||||
`,
|
||||
"image.png": "png data",
|
||||
"module.wasm": "wasm data",
|
||||
},
|
||||
entryPoints: ["./index.js"],
|
||||
outdir: "/out",
|
||||
plugins(build) {
|
||||
// Test multiple file types with custom contents
|
||||
build.onLoad({ filter: /\.(png|wasm)$/ }, async args => {
|
||||
const ext = args.path.split(".").pop();
|
||||
return {
|
||||
loader: "file",
|
||||
contents: `custom ${ext} contents`,
|
||||
};
|
||||
});
|
||||
},
|
||||
run: {
|
||||
stdout: /\.(png|wasm)/,
|
||||
},
|
||||
onAfterBundle(api) {
|
||||
// Verify the build succeeded and files were created
|
||||
api.assertFileExists("index.js");
|
||||
const js = api.readFile("index.js");
|
||||
// Should contain references to the copied files
|
||||
expect(js).toContain('.png"');
|
||||
expect(js).toContain('.wasm"');
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user