Skip to content

Commit 11fa122

Browse files
clydinangular-robot[bot]
authored andcommitted
perf(@angular-devkit/build-angular): enhance Sass package resolution in esbuild builder
The package module resolution logic for Sass stylesheets within the esbuild-based browser application builder has been restructured to limit the need to perform fallback resolution unless fully required. This allows common cases to avoid unnecessary and expensive resolution attempts. This provided a roughly 40% improvement in build times for the Angular Material documentation site.
1 parent c6c045b commit 11fa122

File tree

1 file changed

+42
-20
lines changed
  • packages/angular_devkit/build_angular/src/builders/browser-esbuild

1 file changed

+42
-20
lines changed

packages/angular_devkit/build_angular/src/builders/browser-esbuild/sass-plugin.ts

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -114,32 +114,54 @@ async function compileString(
114114
url,
115115
{ previousResolvedModules }: FileImporterWithRequestContextOptions,
116116
): Promise<URL | null> => {
117-
const result = await resolveUrl(url, previousResolvedModules);
117+
let result = await resolveUrl(url);
118+
if (result.path) {
119+
return pathToFileURL(result.path);
120+
}
118121

119122
// Check for package deep imports
120-
if (!result.path) {
121-
const parts = url.split('/');
122-
const hasScope = parts.length >= 2 && parts[0].startsWith('@');
123-
const [nameOrScope, nameOrFirstPath, ...pathPart] = parts;
124-
const packageName = hasScope ? `${nameOrScope}/${nameOrFirstPath}` : nameOrScope;
125-
126-
const packageResult = await resolveUrl(
127-
packageName + '/package.json',
128-
previousResolvedModules,
123+
const parts = url.split('/');
124+
const hasScope = parts.length >= 2 && parts[0].startsWith('@');
125+
const [nameOrScope, nameOrFirstPath, ...pathPart] = parts;
126+
const packageName = hasScope ? `${nameOrScope}/${nameOrFirstPath}` : nameOrScope;
127+
128+
let packageResult = await resolveUrl(packageName + '/package.json');
129+
130+
if (packageResult.path) {
131+
return pathToFileURL(
132+
join(
133+
dirname(packageResult.path),
134+
!hasScope && nameOrFirstPath ? nameOrFirstPath : '',
135+
...pathPart,
136+
),
129137
);
138+
}
139+
140+
// Check with Yarn PnP workaround using previous resolved modules.
141+
// This is done last to avoid a performance penalty for common cases.
130142

131-
if (packageResult.path) {
132-
return pathToFileURL(
133-
join(
134-
dirname(packageResult.path),
135-
!hasScope && nameOrFirstPath ? nameOrFirstPath : '',
136-
...pathPart,
137-
),
138-
);
139-
}
143+
result = await resolveUrl(url, previousResolvedModules);
144+
if (result.path) {
145+
return pathToFileURL(result.path);
146+
}
147+
148+
packageResult = await resolveUrl(
149+
packageName + '/package.json',
150+
previousResolvedModules,
151+
);
152+
153+
if (packageResult.path) {
154+
return pathToFileURL(
155+
join(
156+
dirname(packageResult.path),
157+
!hasScope && nameOrFirstPath ? nameOrFirstPath : '',
158+
...pathPart,
159+
),
160+
);
140161
}
141162

142-
return result.path ? pathToFileURL(result.path) : null;
163+
// Not found
164+
return null;
143165
},
144166
},
145167
],

0 commit comments

Comments
 (0)