Skip to content

Commit 11cad9d

Browse files
committed
refactor(@angular/build): support multiple results per application build action
The `application` builder may now return more than one build result per rebuild action. This will typically occur when using the development server with HMR enabled. In this scenario, component template update results may be sent to the development server in addition to incremental updates for global styles. TailwindCSS, for instance, may update the global stylesheet for an application based on the usage of styles within a given template.
1 parent 7b15a15 commit 11cad9d

File tree

2 files changed

+23
-9
lines changed

2 files changed

+23
-9
lines changed

packages/angular/build/src/builders/application/build-action.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ export async function* runEsBuildBuildAction(
144144
// Output the first build results after setting up the watcher to ensure that any code executed
145145
// higher in the iterator call stack will trigger the watcher. This is particularly relevant for
146146
// unit tests which execute the builder and modify the file system programmatically.
147-
yield emitOutputResult(result, outputOptions);
147+
yield* emitOutputResults(result, outputOptions);
148148

149149
// Finish if watch mode is not enabled
150150
if (!watcher) {
@@ -196,7 +196,7 @@ export async function* runEsBuildBuildAction(
196196
watcher.remove([...staleWatchFiles]);
197197
}
198198

199-
yield emitOutputResult(
199+
yield* emitOutputResults(
200200
result,
201201
outputOptions,
202202
incrementalResults ? rebuildState.previousOutputInfo : undefined,
@@ -210,7 +210,7 @@ export async function* runEsBuildBuildAction(
210210
}
211211
}
212212

213-
function emitOutputResult(
213+
function* emitOutputResults(
214214
{
215215
outputFiles,
216216
assetFiles,
@@ -223,16 +223,18 @@ function emitOutputResult(
223223
}: ExecutionResult,
224224
outputOptions: NormalizedApplicationBuildOptions['outputOptions'],
225225
previousOutputInfo?: ReadonlyMap<string, { hash: string; type: BuildOutputFileType }>,
226-
): Result {
226+
): Iterable<Result> {
227227
if (errors.length > 0) {
228-
return {
228+
yield {
229229
kind: ResultKind.Failure,
230230
errors: errors as ResultMessage[],
231231
warnings: warnings as ResultMessage[],
232232
detail: {
233233
outputOptions,
234234
},
235235
};
236+
237+
return;
236238
}
237239

238240
// Template updates only exist if no other JS changes have occurred
@@ -247,7 +249,7 @@ function emitOutputResult(
247249
})),
248250
};
249251

250-
return updateResult;
252+
yield updateResult;
251253
}
252254

253255
// Use an incremental result if previous output information is available
@@ -273,6 +275,13 @@ function emitOutputResult(
273275
for (const file of outputFiles) {
274276
removedOutputFiles.delete(file.path);
275277

278+
// Temporarily ignore JS files until Angular compiler plugin refactor to allow
279+
// bypassing application code bundling for template affecting only changes.
280+
// TODO: Remove once refactor is complete.
281+
if (hasTemplateUpdates && /\.[cm]?js(?:\.map)?$/.test(file.path)) {
282+
continue;
283+
}
284+
276285
const previousHash = previousOutputInfo.get(file.path)?.hash;
277286
let needFile = false;
278287
if (previousHash === undefined) {
@@ -312,7 +321,9 @@ function emitOutputResult(
312321
};
313322
}
314323

315-
return incrementalResult;
324+
yield incrementalResult;
325+
326+
return;
316327
}
317328

318329
// Otherwise, use a full result
@@ -343,5 +354,5 @@ function emitOutputResult(
343354
};
344355
}
345356

346-
return result;
357+
yield result;
347358
}

packages/angular/build/src/builders/application/tests/behavior/rebuild-errors_spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,10 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => {
132132

133133
// Make an unrelated change to verify error cache was updated
134134
// Should continue showing no error
135-
await harness.modifyFile('src/main.ts', (content) => content + '\n');
135+
await harness.modifyFile(
136+
'src/main.ts',
137+
(content) => content + '\nconsole.log("changed");',
138+
);
136139

137140
break;
138141
case 4:

0 commit comments

Comments
 (0)