Skip to content

Commit 0f4c665

Browse files
authored
fix: preserve sourcemap mappings for chunks containing user code (#4031)
1 parent 09d6aa6 commit 0f4c665

File tree

2 files changed

+113
-1
lines changed

2 files changed

+113
-1
lines changed

src/build/plugins/sourcemap-min.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function sourcemapMinify() {
1919
// Remove x_google_ignoreList
2020
delete sourcemap.x_google_ignoreList;
2121

22-
if ((sourcemap.sources || []).some((s) => s.includes("node_modules"))) {
22+
if ((sourcemap.sources || []).every((s) => s.includes("node_modules"))) {
2323
sourcemap.mappings = ""; // required key
2424
}
2525

test/unit/sourcemap-min.test.ts

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { describe, expect, it } from "vitest";
2+
import { sourcemapMinify } from "../../src/build/plugins/sourcemap-min.ts";
3+
4+
type BundleAsset = { type: "asset"; source: string };
5+
6+
function createSourcemapAsset(sourcemap: {
7+
sources?: string[];
8+
sourcesContent?: string[];
9+
mappings?: string;
10+
x_google_ignoreList?: number[];
11+
}): BundleAsset {
12+
return {
13+
type: "asset",
14+
source: JSON.stringify({
15+
version: 3,
16+
sources: [],
17+
mappings: "AAAA,CAAC",
18+
...sourcemap,
19+
}),
20+
};
21+
}
22+
23+
function runPlugin(bundle: Record<string, BundleAsset>) {
24+
const plugin = sourcemapMinify();
25+
(plugin.generateBundle as Function).call(null, {}, bundle);
26+
const results: Record<string, ReturnType<typeof JSON.parse>> = {};
27+
for (const [key, asset] of Object.entries(bundle)) {
28+
if (key.endsWith(".map")) {
29+
results[key] = JSON.parse(asset.source);
30+
}
31+
}
32+
return results;
33+
}
34+
35+
describe("sourcemapMinify", () => {
36+
it("removes sourcesContent from all sourcemaps", () => {
37+
const bundle = {
38+
"index.mjs.map": createSourcemapAsset({
39+
sources: ["src/index.ts"],
40+
sourcesContent: ["export default 42;"],
41+
}),
42+
};
43+
const results = runPlugin(bundle);
44+
expect(results["index.mjs.map"].sourcesContent).toBeUndefined();
45+
});
46+
47+
it("removes x_google_ignoreList from all sourcemaps", () => {
48+
const bundle = {
49+
"index.mjs.map": createSourcemapAsset({
50+
sources: ["src/index.ts"],
51+
x_google_ignoreList: [0],
52+
}),
53+
};
54+
const results = runPlugin(bundle);
55+
expect(results["index.mjs.map"].x_google_ignoreList).toBeUndefined();
56+
});
57+
58+
it("wipes mappings for pure library chunks", () => {
59+
const bundle = {
60+
"_libs/express.mjs.map": createSourcemapAsset({
61+
sources: [
62+
"../../node_modules/express/index.js",
63+
"../../node_modules/express/lib/router.js",
64+
],
65+
mappings: "AAAA,CAAC",
66+
}),
67+
};
68+
const results = runPlugin(bundle);
69+
expect(results["_libs/express.mjs.map"].mappings).toBe("");
70+
});
71+
72+
it("preserves mappings for pure user code chunks", () => {
73+
const bundle = {
74+
"_routes/api/hello.mjs.map": createSourcemapAsset({
75+
sources: ["src/routes/api/hello.ts"],
76+
mappings: "AAAA,CAAC",
77+
}),
78+
};
79+
const results = runPlugin(bundle);
80+
expect(results["_routes/api/hello.mjs.map"].mappings).toBe("AAAA,CAAC");
81+
});
82+
83+
it("preserves mappings when library is hoisted into user chunk", () => {
84+
const bundle = {
85+
"_routes/api/hello.mjs.map": createSourcemapAsset({
86+
sources: ["src/routes/api/hello.ts", "../../node_modules/some-lib/index.js"],
87+
mappings: "AAAA,CAAC",
88+
}),
89+
};
90+
const results = runPlugin(bundle);
91+
expect(results["_routes/api/hello.mjs.map"].mappings).toBe("AAAA,CAAC");
92+
});
93+
94+
it("skips non-sourcemap files", () => {
95+
const bundle = {
96+
"index.mjs": { type: "asset" as const, source: "console.log(42)" },
97+
};
98+
runPlugin(bundle as any);
99+
expect(bundle["index.mjs"].source).toBe("console.log(42)");
100+
});
101+
102+
it("handles empty sources array", () => {
103+
const bundle = {
104+
"chunk.mjs.map": createSourcemapAsset({
105+
sources: [],
106+
mappings: "AAAA,CAAC",
107+
}),
108+
};
109+
const results = runPlugin(bundle);
110+
expect(results["chunk.mjs.map"].mappings).toBe("");
111+
});
112+
});

0 commit comments

Comments
 (0)