Skip to content

Commit

Permalink
fix(@angular-devkit/build-angular): use relative sourcemap source pat…
Browse files Browse the repository at this point in the history
…hs for Sass in esbuild builder

The Sass preprocessor's modern API will generate absolute file URLs for the `sources` field of generated
sourcemaps. These URLs will not be properly processed by esbuild and will not be correctly adjusted to be
relative to the workspace root directory for the built application. To correct this behavior, the Sass
generated sourcemaps are now adjusted to remove the `file:` protocol prefix and to make each path relative
to its input file. This allows esbuild to properly resolve and process the paths.
  • Loading branch information
clydin authored and alan-agius4 committed Oct 11, 2022
1 parent 4fcb0a8 commit 1518133
Showing 1 changed file with 13 additions and 3 deletions.
Expand Up @@ -7,8 +7,9 @@
*/

import type { PartialMessage, Plugin, PluginBuild } from 'esbuild';
import { dirname, relative } from 'node:path';
import { fileURLToPath } from 'node:url';
import type { CompileResult } from 'sass';
import { fileURLToPath } from 'url';

export function createSassPlugin(options: { sourcemap: boolean; loadPaths?: string[] }): Plugin {
return {
Expand Down Expand Up @@ -40,7 +41,9 @@ export function createSassPlugin(options: { sourcemap: boolean; loadPaths?: stri

return {
loader: 'css',
contents: sourceMap ? `${css}\n${sourceMapToUrlComment(sourceMap)}` : css,
contents: sourceMap
? `${css}\n${sourceMapToUrlComment(sourceMap, dirname(args.path))}`
: css,
watchFiles: loadedUrls.map((url) => fileURLToPath(url)),
warnings,
};
Expand All @@ -66,7 +69,14 @@ export function createSassPlugin(options: { sourcemap: boolean; loadPaths?: stri
};
}

function sourceMapToUrlComment(sourceMap: Exclude<CompileResult['sourceMap'], undefined>): string {
function sourceMapToUrlComment(
sourceMap: Exclude<CompileResult['sourceMap'], undefined>,
root: string,
): string {
// Remove `file` protocol from all sourcemap sources and adjust to be relative to the input file.
// This allows esbuild to correctly process the paths.
sourceMap.sources = sourceMap.sources.map((source) => relative(root, fileURLToPath(source)));

const urlSourceMap = Buffer.from(JSON.stringify(sourceMap), 'utf-8').toString('base64');

return `/*# sourceMappingURL=data:application/json;charset=utf-8;base64,${urlSourceMap} */`;
Expand Down

0 comments on commit 1518133

Please sign in to comment.