mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
Support absolute paths when bundling HTML (#16149)
This commit is contained in:
@@ -28,12 +28,20 @@ pub fn deinit(this: *HTMLScanner) void {
|
||||
this.import_records.deinitWithAllocator(this.allocator);
|
||||
}
|
||||
|
||||
fn createImportRecord(this: *HTMLScanner, path: []const u8, kind: ImportKind) !void {
|
||||
fn createImportRecord(this: *HTMLScanner, input_path: []const u8, kind: ImportKind) !void {
|
||||
// In HTML, sometimes people do /src/index.js
|
||||
// In that case, we don't want to use the absolute filesystem path, we want to use the path relative to the project root
|
||||
const path_to_use = if (input_path.len > 1 and input_path[0] == '/')
|
||||
bun.path.joinAbsString(bun.fs.FileSystem.instance.top_level_dir, &[_][]const u8{input_path[1..]}, .auto)
|
||||
else
|
||||
input_path;
|
||||
|
||||
const record = ImportRecord{
|
||||
.path = fs.Path.init(try this.allocator.dupe(u8, path)),
|
||||
.path = fs.Path.init(try this.allocator.dupeZ(u8, path_to_use)),
|
||||
.kind = kind,
|
||||
.range = logger.Range.None,
|
||||
};
|
||||
|
||||
try this.import_records.push(this.allocator, record);
|
||||
}
|
||||
|
||||
|
||||
@@ -721,4 +721,60 @@ body {
|
||||
expect(cssBundle).toContain("box-sizing: border-box");
|
||||
},
|
||||
});
|
||||
|
||||
// Test absolute paths in HTML
|
||||
itBundled("html/absolute-paths", {
|
||||
outdir: "out/",
|
||||
files: {
|
||||
"/index.html": `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="/styles/main.css">
|
||||
<script src="/scripts/app.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Absolute Paths</h1>
|
||||
<img src="/images/logo.png">
|
||||
</body>
|
||||
</html>`,
|
||||
"/styles/main.css": "body { margin: 0; }",
|
||||
"/scripts/app.js": "console.log('App loaded')",
|
||||
"/images/logo.png": "fake image content",
|
||||
},
|
||||
experimentalHtml: true,
|
||||
experimentalCss: true,
|
||||
entryPoints: ["/index.html"],
|
||||
onAfterBundle(api) {
|
||||
// Check that absolute paths are handled correctly
|
||||
const htmlBundle = api.readFile("out/index.html");
|
||||
|
||||
// CSS should be bundled and hashed
|
||||
api.expectFile("out/index.html").not.toContain("/styles/main.css");
|
||||
api.expectFile("out/index.html").toMatch(/href=".*\.css"/);
|
||||
|
||||
// JS should be bundled and hashed
|
||||
api.expectFile("out/index.html").not.toContain("/scripts/app.js");
|
||||
api.expectFile("out/index.html").toMatch(/src=".*\.js"/);
|
||||
|
||||
// Image should be hashed
|
||||
api.expectFile("out/index.html").not.toContain("/images/logo.png");
|
||||
api.expectFile("out/index.html").toMatch(/src=".*\.png"/);
|
||||
|
||||
// Get the bundled files and verify their contents
|
||||
const cssMatch = htmlBundle.match(/href="(.*\.css)"/);
|
||||
const jsMatch = htmlBundle.match(/src="(.*\.js)"/);
|
||||
const imgMatch = htmlBundle.match(/src="(.*\.png)"/);
|
||||
|
||||
expect(cssMatch).not.toBeNull();
|
||||
expect(jsMatch).not.toBeNull();
|
||||
expect(imgMatch).not.toBeNull();
|
||||
|
||||
const cssBundle = api.readFile("out/" + cssMatch![1]);
|
||||
const jsBundle = api.readFile("out/" + jsMatch![1]);
|
||||
|
||||
expect(cssBundle).toContain("margin: 0");
|
||||
expect(jsBundle).toContain("App loaded");
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user