Skip to content

Commit

Permalink
refactor(@angular/build): move Angular compilation creation to build …
Browse files Browse the repository at this point in the history
…execution

The creation of the internal Angular compilation used by the internal esbuild
plugin is now created within the main execution phase of the build process.
This is causes no behavior changes but provides the infrastructure for several
addition refactoring improvements including performance improvements of the
HMR process. The private API for the `createCompilerPlugin` has kept its
function signature and currently is not affected by this change.
  • Loading branch information
clydin committed Jan 14, 2025
1 parent 9cccb88 commit 61d98fd
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

import { BuilderContext } from '@angular-devkit/architect';
import { createAngularCompilation } from '../../tools/angular/compilation';
import { SourceFileCache } from '../../tools/esbuild/angular/source-file-cache';
import { generateBudgetStats } from '../../tools/esbuild/budget-stats';
import {
Expand Down Expand Up @@ -108,6 +109,8 @@ export async function executeBuild(
target,
codeBundleCache,
componentStyleBundler,
// Create new reusable compilation for the appropriate mode based on the `jit` plugin option
await createAngularCompilation(!!options.jit, !options.serverEntryPoint),
templateUpdates,
);

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 { AngularCompilation } from '../../tools/angular/compilation';
import { ComponentStylesheetBundler } from '../../tools/esbuild/angular/component-stylesheets';
import { SourceFileCache } from '../../tools/esbuild/angular/source-file-cache';
import {
Expand Down Expand Up @@ -34,6 +35,7 @@ export function setupBundlerContexts(
target: string[],
codeBundleCache: SourceFileCache,
stylesheetBundler: ComponentStylesheetBundler,
angularCompilation: AngularCompilation,
templateUpdates: Map<string, string> | undefined,
): {
typescriptContexts: BundlerContext[];
Expand Down Expand Up @@ -61,6 +63,7 @@ export function setupBundlerContexts(
target,
codeBundleCache,
stylesheetBundler,
angularCompilation,
templateUpdates,
),
),
Expand Down
9 changes: 8 additions & 1 deletion packages/angular/build/src/private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* their existence may change in any future version.
*/

import { NoopCompilation, createAngularCompilation } from './tools/angular/compilation';
import {
CompilerPluginOptions,
createCompilerPlugin as internalCreateCompilerPlugin,
Expand All @@ -38,11 +39,17 @@ export { createJitResourceTransformer } from './tools/angular/transformers/jit-r
export { JavaScriptTransformer } from './tools/esbuild/javascript-transformer';

export function createCompilerPlugin(
pluginOptions: CompilerPluginOptions,
pluginOptions: CompilerPluginOptions & {
browserOnlyBuild?: boolean;
noopTypeScriptCompilation?: boolean;
},
styleOptions: BundleStylesheetOptions & { inlineStyleLanguage: string },
): import('esbuild').Plugin {
return internalCreateCompilerPlugin(
pluginOptions,
pluginOptions.noopTypeScriptCompilation
? new NoopCompilation()
: () => createAngularCompilation(!!pluginOptions.jit, !!pluginOptions.browserOnlyBuild),
new ComponentStylesheetBundler(
styleOptions,
styleOptions.inlineStyleLanguage,
Expand Down
32 changes: 12 additions & 20 deletions packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,7 @@ import { createHash } from 'node:crypto';
import * as path from 'node:path';
import { maxWorkers, useTypeChecking } from '../../../utils/environment-options';
import { AngularHostOptions } from '../../angular/angular-host';
import {
AngularCompilation,
DiagnosticModes,
NoopCompilation,
createAngularCompilation,
} from '../../angular/compilation';
import { AngularCompilation, DiagnosticModes, NoopCompilation } from '../../angular/compilation';
import { JavaScriptTransformer } from '../javascript-transformer';
import { LoadResultCache, createCachedLoad } from '../load-result-cache';
import { logCumulativeDurations, profileAsync, resetCumulativeDurations } from '../profiling';
Expand All @@ -40,10 +35,7 @@ export interface CompilerPluginOptions {
sourcemap: boolean | 'external';
tsconfig: string;
jit?: boolean;
browserOnlyBuild?: boolean;

/** Skip TypeScript compilation setup. This is useful to re-use the TypeScript compilation from another plugin. */
noopTypeScriptCompilation?: boolean;
advancedOptimizations?: boolean;
thirdPartySourcemaps?: boolean;
fileReplacements?: Record<string, string>;
Expand All @@ -58,6 +50,7 @@ export interface CompilerPluginOptions {
// eslint-disable-next-line max-lines-per-function
export function createCompilerPlugin(
pluginOptions: CompilerPluginOptions,
compilationOrFactory: AngularCompilation | (() => Promise<AngularCompilation>),
stylesheetBundler: ComponentStylesheetBundler,
): Plugin {
return {
Expand Down Expand Up @@ -105,6 +98,13 @@ export function createCompilerPlugin(
build.initialOptions.define ??= {};
build.initialOptions.define['ngI18nClosureMode'] ??= 'false';

// The factory is only relevant for compatibility purposes with the private API.
// TODO: Update private API in the next major to allow compilation function factory removal here.
const compilation =
typeof compilationOrFactory === 'function'
? await compilationOrFactory()
: compilationOrFactory;

// The in-memory cache of TypeScript file outputs will be used during the build in `onLoad` callbacks for TS files.
// A string value indicates direct TS/NG output and a Uint8Array indicates fully transformed code.
const typeScriptFileCache =
Expand All @@ -117,10 +117,6 @@ export function createCompilerPlugin(
{ outputFiles?: OutputFile[]; metafile?: Metafile; errors?: PartialMessage[] }
>();

// Create new reusable compilation for the appropriate mode based on the `jit` plugin option
const compilation: AngularCompilation = pluginOptions.noopTypeScriptCompilation
? new NoopCompilation()
: await createAngularCompilation(!!pluginOptions.jit, !!pluginOptions.browserOnlyBuild);
// Compilation is initially assumed to have errors until emitted
let hasCompilationErrors = true;

Expand Down Expand Up @@ -153,8 +149,8 @@ export function createCompilerPlugin(
// dependencies or web worker processing.
let modifiedFiles;
if (
pluginOptions.sourceFileCache?.modifiedFiles.size &&
!pluginOptions.noopTypeScriptCompilation
!(compilation instanceof NoopCompilation) &&
pluginOptions.sourceFileCache?.modifiedFiles.size
) {
// TODO: Differentiate between changed input files and stale output files
modifiedFiles = referencedFileTracker.update(pluginOptions.sourceFileCache.modifiedFiles);
Expand All @@ -168,11 +164,7 @@ export function createCompilerPlugin(
modifiedFiles.forEach((file) => additionalResults.delete(file));
}

if (
!pluginOptions.noopTypeScriptCompilation &&
compilation.update &&
pluginOptions.sourceFileCache?.modifiedFiles.size
) {
if (compilation.update && pluginOptions.sourceFileCache?.modifiedFiles.size) {
await compilation.update(modifiedFiles ?? pluginOptions.sourceFileCache.modifiedFiles);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
SERVER_APP_ENGINE_MANIFEST_FILENAME,
SERVER_APP_MANIFEST_FILENAME,
} from '../../utils/server-rendering/manifest';
import { AngularCompilation, NoopCompilation } from '../angular/compilation';
import { createCompilerPlugin } from './angular/compiler-plugin';
import { ComponentStylesheetBundler } from './angular/component-stylesheets';
import { SourceFileCache } from './angular/source-file-cache';
Expand All @@ -39,6 +40,7 @@ export function createBrowserCodeBundleOptions(
target: string[],
sourceFileCache: SourceFileCache,
stylesheetBundler: ComponentStylesheetBundler,
angularCompilation: AngularCompilation,
templateUpdates: Map<string, string> | undefined,
): BundlerOptionsFactory {
return (loadCache) => {
Expand Down Expand Up @@ -73,6 +75,7 @@ export function createBrowserCodeBundleOptions(
createCompilerPlugin(
// JS/TS options
pluginOptions,
angularCompilation,
// Component stylesheet bundler
stylesheetBundler,
),
Expand Down Expand Up @@ -135,7 +138,9 @@ export function createBrowserPolyfillBundleOptions(
buildOptions.plugins.push(
createCompilerPlugin(
// JS/TS options
{ ...pluginOptions, noopTypeScriptCompilation: true },
pluginOptions,
// Browser compilation handles the actual Angular code compilation
new NoopCompilation(),
// Component stylesheet options are unused for polyfills but required by the plugin
stylesheetBundler,
),
Expand Down Expand Up @@ -276,7 +281,9 @@ export function createServerMainCodeBundleOptions(
createAngularLocalizeInitWarningPlugin(),
createCompilerPlugin(
// JS/TS options
{ ...pluginOptions, noopTypeScriptCompilation: true },
pluginOptions,
// Browser compilation handles the actual Angular code compilation
new NoopCompilation(),
// Component stylesheet bundler
stylesheetBundler,
),
Expand Down Expand Up @@ -416,7 +423,9 @@ export function createSsrEntryCodeBundleOptions(
createAngularLocalizeInitWarningPlugin(),
createCompilerPlugin(
// JS/TS options
{ ...pluginOptions, noopTypeScriptCompilation: true },
pluginOptions,
// Browser compilation handles the actual Angular code compilation
new NoopCompilation(),
// Component stylesheet bundler
stylesheetBundler,
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ export function createCompilerPluginOptions(
const incremental = !!options.watch;

return {
browserOnlyBuild: !options.serverEntryPoint,
sourcemap: !!sourcemapOptions.scripts && (sourcemapOptions.hidden ? 'external' : true),
thirdPartySourcemaps: sourcemapOptions.vendor,
tsconfig,
Expand Down

0 comments on commit 61d98fd

Please sign in to comment.