From e44c360020e880d5456c10c7fa9721925d89bc9d Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 12 Feb 2025 13:02:13 +0000 Subject: [PATCH] fix(@angular/build): correctly map Sass sourcemaps to source files This fix ensures that Sass sourcemaps correctly reference their original source files, improving debugging accuracy. Previously, the sourcemaps may have been misaligned or pointing to incorrect locations, making it harder to trace styles back to their source. This change is also compatible with the updates in esbuild 0.25.0. --- .../application/tests/options/sourcemap_spec.ts | 17 +++++++++++++++++ .../tools/esbuild/stylesheets/sass-language.ts | 13 +++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/angular/build/src/builders/application/tests/options/sourcemap_spec.ts b/packages/angular/build/src/builders/application/tests/options/sourcemap_spec.ts index ddd36477bd99..3cbfa5207c0d 100644 --- a/packages/angular/build/src/builders/application/tests/options/sourcemap_spec.ts +++ b/packages/angular/build/src/builders/application/tests/options/sourcemap_spec.ts @@ -240,5 +240,22 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { .content.not.toContain('sourceMappingURL=app.component.css.map'); harness.expectFile('dist/browser/app.component.css.map').toNotExist(); }); + + it('should generate a correct sourcemap when input file is SCSS', async () => { + await harness.writeFile('src/styles.scss', `* { color: red}`); + + harness.useTarget('build', { + ...BASE_OPTIONS, + sourceMap: true, + styles: ['src/styles.scss'], + }); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBeTrue(); + harness + .expectFile('dist/browser/styles.css.map') + .content.toContain('"sources": ["src/styles.scss"]'); + }); }); }); diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts index bb50543360d0..b3972ac407f4 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts @@ -7,7 +7,7 @@ */ import type { OnLoadResult, PartialMessage, PartialNote, ResolveResult } from 'esbuild'; -import { dirname, join, relative } from 'node:path'; +import { dirname, join } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; import type { CanonicalizeContext, CompileResult, Exception, Syntax } from 'sass'; import type { SassWorkerImplementation } from '../../sass/sass-service'; @@ -170,7 +170,7 @@ async function compileString( return { loader: 'css', - contents: sourceMap ? `${css}\n${sourceMapToUrlComment(sourceMap, dirname(filePath))}` : css, + contents: sourceMap ? `${css}\n${sourceMapToUrlComment(sourceMap)}` : css, watchFiles: loadedUrls.map((url) => fileURLToPath(url)), warnings, }; @@ -199,14 +199,7 @@ async function compileString( } } -function sourceMapToUrlComment( - sourceMap: Exclude, - 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))); - +function sourceMapToUrlComment(sourceMap: Exclude): string { const urlSourceMap = Buffer.from(JSON.stringify(sourceMap), 'utf-8').toString('base64'); return `/*# sourceMappingURL=data:application/json;charset=utf-8;base64,${urlSourceMap} */`;