Skip to content

Commit 9388c8f

Browse files
committed
fix(@angular-devkit/build-angular): correctly resolve Scss partial files in node packages
Prior to this change non relative partial files were not resolved properly. Example we did not try to resolve `@material/button/button` as `@material/button/_button` which caused the compilation to fail.
1 parent f347538 commit 9388c8f

File tree

2 files changed

+53
-4
lines changed

2 files changed

+53
-4
lines changed

packages/angular_devkit/build_angular/src/webpack/configs/styles.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -423,12 +423,30 @@ function getSassResolutionImporter(
423423
});
424424

425425
return {
426-
findFileUrl: (url, { fromImport }): Promise<URL | null> => {
426+
findFileUrl: async (url, { fromImport }): Promise<URL | null> => {
427+
if (url.charAt(0) === '.') {
428+
// Let Sass handle relative imports.
429+
return null;
430+
}
431+
432+
let file: string | undefined;
427433
const resolve = fromImport ? resolveImport : resolveModule;
428434

429-
return resolve(root, url)
430-
.then((file) => pathToFileURL(file))
431-
.catch(() => null);
435+
try {
436+
file = await resolve(root, url);
437+
} catch {
438+
// Try to resolve a partial file
439+
// @use '@material/button/button' as mdc-button;
440+
// `@material/button/button` -> `@material/button/_button`
441+
const lastSlashIndex = url.lastIndexOf('/');
442+
const underscoreIndex = lastSlashIndex + 1;
443+
if (underscoreIndex > 0 && url.charAt(underscoreIndex) !== '_') {
444+
const partialFileUrl = `${url.slice(0, underscoreIndex)}_${url.slice(underscoreIndex)}`;
445+
file = await resolve(root, partialFileUrl).catch(() => undefined);
446+
}
447+
}
448+
449+
return file ? pathToFileURL(file) : null;
432450
},
433451
};
434452
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { installPackage } from '../../../utils/packages';
2+
import { writeMultipleFiles, deleteFile, replaceInFile } from '../../../utils/fs';
3+
import { ng } from '../../../utils/process';
4+
import { updateJsonFile } from '../../../utils/project';
5+
6+
export default async function () {
7+
// Supports resolving node_modules with are pointing to partial files partial files.
8+
// @material/button/button below points to @material/button/_button.scss
9+
// https://unpkg.com/browse/@material/button@14.0.0/_button.scss
10+
11+
await installPackage('@material/button@14.0.0');
12+
13+
await writeMultipleFiles({
14+
'src/styles.scss': `
15+
@use '@material/button/button' as mat;
16+
`,
17+
'src/app/app.component.scss': `
18+
@use '@material/button/button' as mat;
19+
`,
20+
});
21+
22+
await updateJsonFile('angular.json', (workspaceJson) => {
23+
const appArchitect = workspaceJson.projects['test-project'].architect;
24+
appArchitect.build.options.styles = ['src/styles.scss'];
25+
});
26+
27+
await deleteFile('src/app/app.component.css');
28+
await replaceInFile('src/app/app.component.ts', './app.component.css', './app.component.scss');
29+
30+
await ng('build', '--source-map', '--configuration=development');
31+
}

0 commit comments

Comments
 (0)