diff --git a/packages/angular/build/src/builders/application/execute-build.ts b/packages/angular/build/src/builders/application/execute-build.ts index 43cbf41d52a6..d6e121a6bd20 100644 --- a/packages/angular/build/src/builders/application/execute-build.ts +++ b/packages/angular/build/src/builders/application/execute-build.ts @@ -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 { @@ -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, ); diff --git a/packages/angular/build/src/builders/application/setup-bundling.ts b/packages/angular/build/src/builders/application/setup-bundling.ts index c0ef33ab2ff8..413c625eb81c 100644 --- a/packages/angular/build/src/builders/application/setup-bundling.ts +++ b/packages/angular/build/src/builders/application/setup-bundling.ts @@ -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 { @@ -34,6 +35,7 @@ export function setupBundlerContexts( target: string[], codeBundleCache: SourceFileCache, stylesheetBundler: ComponentStylesheetBundler, + angularCompilation: AngularCompilation, templateUpdates: Map | undefined, ): { typescriptContexts: BundlerContext[]; @@ -61,6 +63,7 @@ export function setupBundlerContexts( target, codeBundleCache, stylesheetBundler, + angularCompilation, templateUpdates, ), ), diff --git a/packages/angular/build/src/private.ts b/packages/angular/build/src/private.ts index 069c7f25c868..1975efaa3610 100644 --- a/packages/angular/build/src/private.ts +++ b/packages/angular/build/src/private.ts @@ -13,6 +13,7 @@ * their existence may change in any future version. */ +import { NoopCompilation, createAngularCompilation } from './tools/angular/compilation'; import { CompilerPluginOptions, createCompilerPlugin as internalCreateCompilerPlugin, @@ -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, diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 798adc090f8e..5cfe973a7372 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -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'; @@ -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; @@ -58,6 +50,7 @@ export interface CompilerPluginOptions { // eslint-disable-next-line max-lines-per-function export function createCompilerPlugin( pluginOptions: CompilerPluginOptions, + compilationOrFactory: AngularCompilation | (() => Promise), stylesheetBundler: ComponentStylesheetBundler, ): Plugin { return { @@ -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 = @@ -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; @@ -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); @@ -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); } diff --git a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts index ff54f980b100..58bdd78c2dcf 100644 --- a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts +++ b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts @@ -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'; @@ -39,6 +40,7 @@ export function createBrowserCodeBundleOptions( target: string[], sourceFileCache: SourceFileCache, stylesheetBundler: ComponentStylesheetBundler, + angularCompilation: AngularCompilation, templateUpdates: Map | undefined, ): BundlerOptionsFactory { return (loadCache) => { @@ -73,6 +75,7 @@ export function createBrowserCodeBundleOptions( createCompilerPlugin( // JS/TS options pluginOptions, + angularCompilation, // Component stylesheet bundler stylesheetBundler, ), @@ -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, ), @@ -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, ), @@ -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, ), diff --git a/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts b/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts index 93a92fa7e9a1..355bbad228ff 100644 --- a/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts +++ b/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts @@ -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,