Skip to content

feat(@angular/ssr): add modulepreload for lazy-loaded routes #28919

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/angular/build/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ ts_library(
"@npm//@angular/compiler-cli",
"@npm//@babel/core",
"@npm//prettier",
"@npm//typescript",
],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,13 @@ export async function executeBuild(

// Perform i18n translation inlining if enabled
if (i18nOptions.shouldInline) {
const result = await inlineI18n(options, executionResult, initialFiles);
const result = await inlineI18n(metafile, options, executionResult, initialFiles);
executionResult.addErrors(result.errors);
executionResult.addWarnings(result.warnings);
executionResult.addPrerenderedRoutes(result.prerenderedRoutes);
} else {
const result = await executePostBundleSteps(
metafile,
options,
executionResult.outputFiles,
executionResult.assetFiles,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* found in the LICENSE file at https://angular.dev/license
*/

import type { Metafile } from 'esbuild';
import assert from 'node:assert';
import {
BuildOutputFile,
Expand Down Expand Up @@ -34,6 +35,7 @@ import { OutputMode } from './schema';

/**
* Run additional builds steps including SSG, AppShell, Index HTML file and Service worker generation.
* @param metafile An esbuild metafile object.
* @param options The normalized application builder options used to create the build.
* @param outputFiles The output files of an executed build.
* @param assetFiles The assets of an executed build.
Expand All @@ -42,6 +44,7 @@ import { OutputMode } from './schema';
*/
// eslint-disable-next-line max-lines-per-function
export async function executePostBundleSteps(
metafile: Metafile,
options: NormalizedApplicationBuildOptions,
outputFiles: BuildOutputFile[],
assetFiles: BuildOutputAsset[],
Expand Down Expand Up @@ -71,6 +74,7 @@ export async function executePostBundleSteps(
serverEntryPoint,
prerenderOptions,
appShellOptions,
publicPath,
workspaceRoot,
partialSSRBuild,
} = options;
Expand Down Expand Up @@ -108,6 +112,7 @@ export async function executePostBundleSteps(
}

// Create server manifest
const initialFilesPaths = new Set(initialFiles.keys());
if (serverEntryPoint) {
const { manifestContent, serverAssetsChunks } = generateAngularServerAppManifest(
additionalHtmlOutputFiles,
Expand All @@ -116,6 +121,9 @@ export async function executePostBundleSteps(
undefined,
locale,
baseHref,
initialFilesPaths,
metafile,
publicPath,
);

additionalOutputFiles.push(
Expand Down Expand Up @@ -197,6 +205,9 @@ export async function executePostBundleSteps(
serializableRouteTreeNodeForManifest,
locale,
baseHref,
initialFilesPaths,
metafile,
publicPath,
);

for (const chunk of serverAssetsChunks) {
Expand Down
4 changes: 4 additions & 0 deletions packages/angular/build/src/builders/application/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { BuilderContext } from '@angular-devkit/architect';
import type { Metafile } from 'esbuild';
import { join } from 'node:path';
import { BuildOutputFileType, InitialFileRecord } from '../../tools/esbuild/bundler-context';
import {
Expand All @@ -23,11 +24,13 @@ import { NormalizedApplicationBuildOptions, getLocaleBaseHref } from './options'
/**
* Inlines all active locales as specified by the application build options into all
* application JavaScript files created during the build.
* @param metafile An esbuild metafile object.
* @param options The normalized application builder options used to create the build.
* @param executionResult The result of an executed build.
* @param initialFiles A map containing initial file information for the executed build.
*/
export async function inlineI18n(
metafile: Metafile,
options: NormalizedApplicationBuildOptions,
executionResult: ExecutionResult,
initialFiles: Map<string, InitialFileRecord>,
Expand Down Expand Up @@ -79,6 +82,7 @@ export async function inlineI18n(
additionalOutputFiles,
prerenderedRoutes: generatedRoutes,
} = await executePostBundleSteps(
metafile,
{
...options,
baseHref: getLocaleBaseHref(baseHref, i18nOptions, locale) ?? baseHref,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
ensureSourceFileVersions,
} from '../angular-host';
import { replaceBootstrap } from '../transformers/jit-bootstrap-transformer';
import { lazyRoutesTransformer } from '../transformers/lazy-routes-transformer';
import { createWorkerTransformer } from '../transformers/web-worker-transformer';
import { AngularCompilation, DiagnosticModes, EmitFileResult } from './angular-compilation';
import { collectHmrCandidates } from './hmr-candidates';
Expand Down Expand Up @@ -47,6 +48,10 @@ class AngularCompilationState {
export class AotCompilation extends AngularCompilation {
#state?: AngularCompilationState;

constructor(private readonly browserOnlyBuild: boolean) {
super();
}

async initialize(
tsconfig: string,
hostOptions: AngularHostOptions,
Expand Down Expand Up @@ -314,8 +319,12 @@ export class AotCompilation extends AngularCompilation {
transformers.before ??= [];
transformers.before.push(
replaceBootstrap(() => typeScriptProgram.getProgram().getTypeChecker()),
webWorkerTransform,
);
transformers.before.push(webWorkerTransform);

if (!this.browserOnlyBuild) {
transformers.before.push(lazyRoutesTransformer(compilerOptions, compilerHost));
}

// Emit is handled in write file callback when using TypeScript
if (useTypeScriptTranspilation) {
Expand Down
12 changes: 8 additions & 4 deletions packages/angular/build/src/tools/angular/compilation/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,26 @@ import type { AngularCompilation } from './angular-compilation';
* compilation either for AOT or JIT mode. By default a parallel compilation is created
* that uses a Node.js worker thread.
* @param jit True, for Angular JIT compilation; False, for Angular AOT compilation.
* @param browserOnlyBuild True, for browser only builds; False, for browser and server builds.
* @returns An instance of an Angular compilation object.
*/
export async function createAngularCompilation(jit: boolean): Promise<AngularCompilation> {
export async function createAngularCompilation(
jit: boolean,
browserOnlyBuild: boolean,
): Promise<AngularCompilation> {
if (useParallelTs) {
const { ParallelCompilation } = await import('./parallel-compilation');

return new ParallelCompilation(jit);
return new ParallelCompilation(jit, browserOnlyBuild);
}

if (jit) {
const { JitCompilation } = await import('./jit-compilation');

return new JitCompilation();
return new JitCompilation(browserOnlyBuild);
} else {
const { AotCompilation } = await import('./aot-compilation');

return new AotCompilation();
return new AotCompilation(browserOnlyBuild);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { loadEsmModule } from '../../../utils/load-esm';
import { profileSync } from '../../esbuild/profiling';
import { AngularHostOptions, createAngularCompilerHost } from '../angular-host';
import { createJitResourceTransformer } from '../transformers/jit-resource-transformer';
import { lazyRoutesTransformer } from '../transformers/lazy-routes-transformer';
import { createWorkerTransformer } from '../transformers/web-worker-transformer';
import { AngularCompilation, DiagnosticModes, EmitFileResult } from './angular-compilation';

Expand All @@ -29,6 +30,10 @@ class JitCompilationState {
export class JitCompilation extends AngularCompilation {
#state?: JitCompilationState;

constructor(private readonly browserOnlyBuild: boolean) {
super();
}

async initialize(
tsconfig: string,
hostOptions: AngularHostOptions,
Expand Down Expand Up @@ -116,8 +121,8 @@ export class JitCompilation extends AngularCompilation {
replaceResourcesTransform,
webWorkerTransform,
} = this.#state;
const buildInfoFilename =
typeScriptProgram.getCompilerOptions().tsBuildInfoFile ?? '.tsbuildinfo';
const compilerOptions = typeScriptProgram.getCompilerOptions();
const buildInfoFilename = compilerOptions.tsBuildInfoFile ?? '.tsbuildinfo';

const emittedFiles: EmitFileResult[] = [];
const writeFileCallback: ts.WriteFileCallback = (filename, contents, _a, _b, sourceFiles) => {
Expand All @@ -140,6 +145,10 @@ export class JitCompilation extends AngularCompilation {
],
};

if (!this.browserOnlyBuild) {
transformers.before.push(lazyRoutesTransformer(compilerOptions, compilerHost));
}

// TypeScript will loop until there are no more affected files in the program
while (
typeScriptProgram.emitNextAffectedFile(writeFileCallback, undefined, undefined, transformers)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ import { AngularCompilation, DiagnosticModes, EmitFileResult } from './angular-c
export class ParallelCompilation extends AngularCompilation {
readonly #worker: WorkerPool;

constructor(readonly jit: boolean) {
constructor(
private readonly jit: boolean,
private readonly browserOnlyBuild: boolean,
) {
super();

// TODO: Convert to import.meta usage during ESM transition
Expand Down Expand Up @@ -99,6 +102,7 @@ export class ParallelCompilation extends AngularCompilation {
fileReplacements: hostOptions.fileReplacements,
tsconfig,
jit: this.jit,
browserOnlyBuild: this.browserOnlyBuild,
stylesheetPort: stylesheetChannel.port2,
optionsPort: optionsChannel.port2,
optionsSignal,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { JitCompilation } from './jit-compilation';

export interface InitRequest {
jit: boolean;
browserOnlyBuild: boolean;
tsconfig: string;
fileReplacements?: Record<string, string>;
stylesheetPort: MessagePort;
Expand All @@ -31,7 +32,9 @@ let compilation: AngularCompilation | undefined;
const sourceFileCache = new SourceFileCache();

export async function initialize(request: InitRequest) {
compilation ??= request.jit ? new JitCompilation() : new AotCompilation();
compilation ??= request.jit
? new JitCompilation(request.browserOnlyBuild)
: new AotCompilation(request.browserOnlyBuild);

const stylesheetRequests = new Map<string, [(value: string) => void, (reason: Error) => void]>();
request.stylesheetPort.on('message', ({ requestId, value, error }) => {
Expand Down
Loading
Loading