Skip to content

Commit 3ec6e15

Browse files
committed
fix(@angular/build): inline external sourcemaps for workspace library files
When no Babel plugins are required, the JavaScript transformer returns library files as-is, preserving the comment but never reading the referenced map file from disk. esbuild does not follow external sourcemap links in input files, so the chain from bundled output back to the original TypeScript source is never formed. Read the external map file and return an inline base64 sourcemap instead. esbuild processes inline sourcemaps from input files correctly, allowing it to compose the full sourcemap chain through to the original TypeScript source.
1 parent 98450e1 commit 3ec6e15

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,34 @@ async function transformWithBabel(
9595
// If no additional transformations are needed, return the data directly
9696
if (plugins.length === 0) {
9797
// Strip sourcemaps if they should not be used
98-
return useInputSourcemap ? data : data.replace(/^\/\/# sourceMappingURL=[^\r\n]*/gm, '');
98+
if (!useInputSourcemap) {
99+
return data.replace(/^\/\/# sourceMappingURL=[^\r\n]*/gm, '');
100+
}
101+
102+
// Inline any external sourceMappingURL so esbuild can chain through to the original source.
103+
// When no Babel plugins run, external map references are preserved in the returned data but
104+
// esbuild does not follow them. Converting to an inline base64 map allows esbuild to compose
105+
// the full sourcemap chain from bundle output back to the original TypeScript source.
106+
const externalMapMatch = /^\/\/# sourceMappingURL=(?!data:)([^\r\n]+)/m.exec(data);
107+
if (externalMapMatch) {
108+
const mapPath = path.resolve(path.dirname(filename), externalMapMatch[1]);
109+
try {
110+
const mapContent = await fs.promises.readFile(mapPath, 'utf-8');
111+
const inlineMap = Buffer.from(mapContent).toString('base64');
112+
return data.replace(
113+
/^\/\/# sourceMappingURL=[^\r\n]*/m,
114+
`//# sourceMappingURL=data:application/json;charset=utf-8;base64,${inlineMap}`,
115+
);
116+
} catch (error) {
117+
// Map file not readable; return data with the original external reference
118+
// eslint-disable-next-line no-console
119+
console.warn(
120+
`Unable to inline sourcemap for '${filename}': ${error instanceof Error ? error.message : error}`,
121+
);
122+
}
123+
}
124+
125+
return data;
99126
}
100127

101128
const result = await transformAsync(data, {

0 commit comments

Comments
 (0)