Skip to content

Commit

Permalink
fix(@angular-devkit/build-angular): correctly resolve Sass partial fi…
Browse files Browse the repository at this point in the history
…les 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.
  • Loading branch information
alan-agius4 committed Oct 11, 2022
1 parent 5228c23 commit 4fcb0a8
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 4 deletions.
Expand Up @@ -423,12 +423,30 @@ function getSassResolutionImporter(
});

return {
findFileUrl: (url, { fromImport }): Promise<URL | null> => {
findFileUrl: async (url, { fromImport }): Promise<URL | null> => {
if (url.charAt(0) === '.') {
// Let Sass handle relative imports.
return null;
}

let file: string | undefined;
const resolve = fromImport ? resolveImport : resolveModule;

return resolve(root, url)
.then((file) => pathToFileURL(file))
.catch(() => null);
try {
file = await resolve(root, url);
} catch {
// Try to resolve a partial file
// @use '@material/button/button' as mdc-button;
// `@material/button/button` -> `@material/button/_button`
const lastSlashIndex = url.lastIndexOf('/');
const underscoreIndex = lastSlashIndex + 1;
if (underscoreIndex > 0 && url.charAt(underscoreIndex) !== '_') {
const partialFileUrl = `${url.slice(0, underscoreIndex)}_${url.slice(underscoreIndex)}`;
file = await resolve(root, partialFileUrl).catch(() => undefined);
}
}

return file ? pathToFileURL(file) : null;
},
};
}
31 changes: 31 additions & 0 deletions tests/legacy-cli/e2e/tests/build/styles/scss-partial-resolution.ts
@@ -0,0 +1,31 @@
import { installPackage } from '../../../utils/packages';
import { writeMultipleFiles, deleteFile, replaceInFile } from '../../../utils/fs';
import { ng } from '../../../utils/process';
import { updateJsonFile } from '../../../utils/project';

export default async function () {
// Supports resolving node_modules with are pointing to partial files partial files.
// @material/button/button below points to @material/button/_button.scss
// https://unpkg.com/browse/@material/button@14.0.0/_button.scss

await installPackage('@material/button@14.0.0');

await writeMultipleFiles({
'src/styles.scss': `
@use '@material/button/button' as mat;
`,
'src/app/app.component.scss': `
@use '@material/button/button' as mat;
`,
});

await updateJsonFile('angular.json', (workspaceJson) => {
const appArchitect = workspaceJson.projects['test-project'].architect;
appArchitect.build.options.styles = ['src/styles.scss'];
});

await deleteFile('src/app/app.component.css');
await replaceInFile('src/app/app.component.ts', './app.component.css', './app.component.scss');

await ng('build', '--configuration=development');
}

0 comments on commit 4fcb0a8

Please sign in to comment.