Skip to content

Commit dfeb37f

Browse files
committed
perf(@angular/build): directly check code for Angular partial linking
To more completely avoid having to load any Angular compiler linking code when analyzing for code transformations during a build, the declaration function checks are now performed directly. This is in contrast to the previous behavior that required importing the linker code to use a helper function included in the `@angular/compiler-cli` package. Avoiding the need to load and parse a potentially large amount of code to perform the check can improve performance for the cases where no linking is required. To ensure the check stays up to date and while the list of function names rarely changes, the linker must always use the existing function name prefix (`ɵɵngDeclare`) for any declaration functions.
1 parent 233495f commit dfeb37f

File tree

1 file changed

+12
-16
lines changed

1 file changed

+12
-16
lines changed

packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ interface JavaScriptTransformRequest {
2727
const textDecoder = new TextDecoder();
2828
const textEncoder = new TextEncoder();
2929

30+
/**
31+
* The function name prefix for all Angular partial compilation functions.
32+
* Used to determine if linking of a JavaScript file is required.
33+
* If any additional declarations are added or otherwise changed in the linker,
34+
* the names MUST begin with this prefix.
35+
*/
36+
const LINKER_DECLARATION_PREFIX = 'ɵɵngDeclare';
37+
3038
export default async function transformJavaScript(
3139
request: JavaScriptTransformRequest,
3240
): Promise<unknown> {
@@ -46,11 +54,6 @@ let linkerPluginCreator:
4654
| typeof import('@angular/compiler-cli/linker/babel').createEs2015LinkerPlugin
4755
| undefined;
4856

49-
/**
50-
* Cached instance of the compiler-cli linker's needsLinking function.
51-
*/
52-
let needsLinking: typeof import('@angular/compiler-cli/linker').needsLinking | undefined;
53-
5457
async function transformWithBabel(
5558
filename: string,
5659
data: string,
@@ -125,17 +128,10 @@ async function requiresLinking(path: string, source: string): Promise<boolean> {
125128
return false;
126129
}
127130

128-
if (!needsLinking) {
129-
// Load ESM `@angular/compiler-cli/linker` using the TypeScript dynamic import workaround.
130-
// Once TypeScript provides support for keeping the dynamic import this workaround can be
131-
// changed to a direct dynamic import.
132-
const linkerModule = await loadEsmModule<typeof import('@angular/compiler-cli/linker')>(
133-
'@angular/compiler-cli/linker',
134-
);
135-
needsLinking = linkerModule.needsLinking;
136-
}
137-
138-
return needsLinking(path, source);
131+
// Check if the source code includes one of the declaration functions.
132+
// There is a low chance of a false positive but the names are fairly unique
133+
// and the result would be an unnecessary no-op additional plugin pass.
134+
return source.includes(LINKER_DECLARATION_PREFIX);
139135
}
140136

141137
async function createLinkerPlugin(options: Omit<JavaScriptTransformRequest, 'filename' | 'data'>) {

0 commit comments

Comments
 (0)