Skip to content

Commit 172f3c2

Browse files
clydinjkrems
authored andcommitted
fix(@angular/build): improve URL rebasing for hyphenated Sass namespaced variables
Sass variable namespaces can contain either a hyphen or underscore in the namespace identifier. The URL rebasing support within the Angular CLI will now account for these type of namespaces and rebase the evaluated URL as expected. (cherry picked from commit f96bb86)
1 parent 52dcd55 commit 172f3c2

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

packages/angular/build/src/builders/application/tests/behavior/stylesheet-url-resolution_spec.ts

+54
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,60 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
243243
harness.expectFile('dist/browser/media/logo.svg').toExist();
244244
});
245245

246+
it('should rebase a URL with a hyphen-namespaced Sass variable referencing a local resource', async () => {
247+
await harness.writeFiles({
248+
'src/styles.scss': `@use 'theme/a';`,
249+
'src/theme/a.scss': `
250+
@use './b' as named-hyphen;
251+
.a {
252+
background-image: url(named-hyphen.$my-var)
253+
}
254+
`,
255+
'src/theme/b.scss': `@forward './c.scss' show $my-var;`,
256+
'src/theme/c.scss': `$my-var: "./images/logo.svg";`,
257+
'src/theme/images/logo.svg': `<svg></svg>`,
258+
});
259+
260+
harness.useTarget('build', {
261+
...BASE_OPTIONS,
262+
outputHashing: OutputHashing.None,
263+
styles: ['src/styles.scss'],
264+
});
265+
266+
const { result } = await harness.executeOnce();
267+
expect(result?.success).toBeTrue();
268+
269+
harness.expectFile('dist/browser/styles.css').content.toContain(`url("./media/logo.svg")`);
270+
harness.expectFile('dist/browser/media/logo.svg').toExist();
271+
});
272+
273+
it('should rebase a URL with a underscore-namespaced Sass variable referencing a local resource', async () => {
274+
await harness.writeFiles({
275+
'src/styles.scss': `@use 'theme/a';`,
276+
'src/theme/a.scss': `
277+
@use './b' as named_underscore;
278+
.a {
279+
background-image: url(named_underscore.$my-var)
280+
}
281+
`,
282+
'src/theme/b.scss': `@forward './c.scss' show $my-var;`,
283+
'src/theme/c.scss': `$my-var: "./images/logo.svg";`,
284+
'src/theme/images/logo.svg': `<svg></svg>`,
285+
});
286+
287+
harness.useTarget('build', {
288+
...BASE_OPTIONS,
289+
outputHashing: OutputHashing.None,
290+
styles: ['src/styles.scss'],
291+
});
292+
293+
const { result } = await harness.executeOnce();
294+
expect(result?.success).toBeTrue();
295+
296+
harness.expectFile('dist/browser/styles.css').content.toContain(`url("./media/logo.svg")`);
297+
harness.expectFile('dist/browser/media/logo.svg').toExist();
298+
});
299+
246300
it('should rebase a URL with a Sass variable referencing a local resource', async () => {
247301
await harness.writeFiles({
248302
'src/styles.scss': `@use 'theme/a';`,

packages/angular/build/src/tools/sass/rebasing-importer.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ abstract class UrlRebasingImporter implements Importer<'sync'> {
7777
}
7878

7979
// Sass variable usage either starts with a `$` or contains a namespace and a `.$`
80-
const valueNormalized = value[0] === '$' || /^\w+\.\$/.test(value) ? `#{${value}}` : value;
80+
const valueNormalized =
81+
value[0] === '$' || /^\w[\w_-]*\.\$/.test(value) ? `#{${value}}` : value;
8182
const rebasedPath = relative(this.entryDirectory, stylesheetDirectory);
8283

8384
// Normalize path separators and escape characters

0 commit comments

Comments
 (0)