Skip to content

Commit

Permalink
refactor(@angular/build): support multiple results per application bu…
Browse files Browse the repository at this point in the history
…ild 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.
  • Loading branch information
clydin committed Jan 8, 2025
1 parent 04b8184 commit aab4248
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions packages/angular/build/src/builders/application/build-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ export async function* runEsBuildBuildAction(
// Output the first build results after setting up the watcher to ensure that any code executed
// higher in the iterator call stack will trigger the watcher. This is particularly relevant for
// unit tests which execute the builder and modify the file system programmatically.
yield emitOutputResult(result, outputOptions);
yield* emitOutputResults(result, outputOptions);

// Finish if watch mode is not enabled
if (!watcher) {
Expand Down Expand Up @@ -196,11 +196,13 @@ export async function* runEsBuildBuildAction(
watcher.remove([...staleWatchFiles]);
}

yield emitOutputResult(
for (const outputResult of emitOutputResults(
result,
outputOptions,
incrementalResults ? rebuildState.previousOutputInfo : undefined,
);
)) {
yield outputResult;
}
}
} finally {
// Stop the watcher and cleanup incremental rebuild state
Expand All @@ -210,7 +212,7 @@ export async function* runEsBuildBuildAction(
}
}

function emitOutputResult(
function* emitOutputResults(
{
outputFiles,
assetFiles,
Expand All @@ -223,16 +225,18 @@ function emitOutputResult(
}: ExecutionResult,
outputOptions: NormalizedApplicationBuildOptions['outputOptions'],
previousOutputInfo?: ReadonlyMap<string, { hash: string; type: BuildOutputFileType }>,
): Result {
): Iterable<Result> {
if (errors.length > 0) {
return {
yield {
kind: ResultKind.Failure,
errors: errors as ResultMessage[],
warnings: warnings as ResultMessage[],
detail: {
outputOptions,
},
};

return;
}

// Template updates only exist if no other JS changes have occurred
Expand All @@ -247,7 +251,7 @@ function emitOutputResult(
})),
};

return updateResult;
yield updateResult;
}

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

// Temporarily ignore JS files until Angular compiler plugin refactor to allow
// bypassing application code bundling for template affecting only changes.
// TODO: Remove once refactor is complete.
if (hasTemplateUpdates && /\.js(?:\.map)?$/.test(file.path)) {
continue;
}

const previousHash = previousOutputInfo.get(file.path)?.hash;
let needFile = false;
if (previousHash === undefined) {
Expand Down Expand Up @@ -312,7 +323,9 @@ function emitOutputResult(
};
}

return incrementalResult;
yield incrementalResult;

return;
}

// Otherwise, use a full result
Expand Down Expand Up @@ -343,5 +356,5 @@ function emitOutputResult(
};
}

return result;
yield result;
}

0 comments on commit aab4248

Please sign in to comment.