diff --git a/packages/angular/build/src/builders/application/execute-build.ts b/packages/angular/build/src/builders/application/execute-build.ts index 0654cd965558..ff09c3ad74f8 100644 --- a/packages/angular/build/src/builders/application/execute-build.ts +++ b/packages/angular/build/src/builders/application/execute-build.ts @@ -8,7 +8,6 @@ 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 { BuildOutputFileType, @@ -51,6 +50,7 @@ export async function executeBuild( assets, cacheOptions, serverEntryPoint, + codeBundleCache, baseHref, ssrOptions, verbose, @@ -70,13 +70,11 @@ export async function executeBuild( // Reuse rebuild state or create new bundle contexts for code and global stylesheets let bundlerContexts; let componentStyleBundler; - let codeBundleCache; let bundlingResult: BundleContextResult; let templateUpdates: Map | undefined; if (rebuildState) { bundlerContexts = rebuildState.rebuildContexts; componentStyleBundler = rebuildState.componentStyleBundler; - codeBundleCache = rebuildState.codeBundleCache; templateUpdates = rebuildState.templateUpdates; // Reset template updates for new rebuild templateUpdates?.clear(); @@ -99,7 +97,6 @@ export async function executeBuild( bundlingResult = BundlerContext.mergeResults([bundlingResult, ...typescriptResults]); } else { const target = transformSupportedBrowsersToTargets(browsers); - codeBundleCache = new SourceFileCache(cacheOptions.enabled ? cacheOptions.path : undefined); componentStyleBundler = createComponentStyleBundler(options, target); if (options.templateUpdates) { templateUpdates = new Map(); diff --git a/packages/angular/build/src/builders/application/options.ts b/packages/angular/build/src/builders/application/options.ts index 83b7ea428f35..d021bdcbf386 100644 --- a/packages/angular/build/src/builders/application/options.ts +++ b/packages/angular/build/src/builders/application/options.ts @@ -12,6 +12,7 @@ import { realpathSync } from 'node:fs'; import { access, constants, readFile } from 'node:fs/promises'; import { createRequire } from 'node:module'; import path from 'node:path'; +import { SourceFileCache } from '../../tools/esbuild/angular/source-file-cache'; import { normalizeAssetPatterns, normalizeOptimization, normalizeSourceMaps } from '../../utils'; import { supportColor } from '../../utils/color'; import { useJSONBuildLogs, usePartialSsrBuild } from '../../utils/environment-options'; @@ -70,6 +71,9 @@ interface InternalOptions { */ entryPoints?: Set | Map; + /** Allow to programatically provide a shared cache */ + codeBundleCache?: SourceFileCache; + /** File extension to use for the generated output files. */ outExtension?: 'js' | 'mjs'; @@ -164,8 +168,11 @@ export async function normalizeOptions( const { projectRoot, projectSourceRoot } = getProjectRootPaths(workspaceRoot, projectMetadata); // Gather persistent caching option and provide a project specific cache location - const cacheOptions = normalizeCacheOptions(projectMetadata, workspaceRoot); - cacheOptions.path = path.join(cacheOptions.path, projectName); + const cacheOptions = normalizeCacheOptions(projectMetadata, workspaceRoot, projectName); + + const codeBundleCache = + options.codeBundleCache ?? + new SourceFileCache(cacheOptions.enabled ? cacheOptions.path : undefined); const i18nOptions: I18nOptions & { duplicateTranslationBehavior?: I18NTranslation; @@ -446,6 +453,7 @@ export async function normalizeOptions( allowedCommonJsDependencies, baseHref, cacheOptions, + codeBundleCache, crossOrigin, externalDependencies: normalizeExternals(externalDependencies), externalPackages: diff --git a/packages/angular/build/src/builders/unit-test/options.ts b/packages/angular/build/src/builders/unit-test/options.ts index 72b5f3eb3e8d..959a8d3361b7 100644 --- a/packages/angular/build/src/builders/unit-test/options.ts +++ b/packages/angular/build/src/builders/unit-test/options.ts @@ -47,8 +47,7 @@ export async function normalizeOptions( const { projectRoot, projectSourceRoot } = getProjectRootPaths(workspaceRoot, projectMetadata); // Gather persistent caching option and provide a project specific cache location - const cacheOptions = normalizeCacheOptions(projectMetadata, workspaceRoot); - cacheOptions.path = path.join(cacheOptions.path, projectName); + const cacheOptions = normalizeCacheOptions(projectMetadata, workspaceRoot, projectName); // Target specifier defaults to the current project's build target using a development configuration const buildTargetSpecifier = options.buildTarget ?? `::development`; diff --git a/packages/angular/build/src/utils/normalize-cache.ts b/packages/angular/build/src/utils/normalize-cache.ts index f272f6a78e45..fbf285f2de82 100644 --- a/packages/angular/build/src/utils/normalize-cache.ts +++ b/packages/angular/build/src/utils/normalize-cache.ts @@ -42,6 +42,7 @@ function hasCacheMetadata(value: unknown): value is { cli: { cache: CacheMetadat export function normalizeCacheOptions( projectMetadata: unknown, worspaceRoot: string, + projectName?: string, ): NormalizedCachedOptions { const cacheMetadata = hasCacheMetadata(projectMetadata) ? projectMetadata.cli.cache : {}; @@ -67,9 +68,13 @@ export function normalizeCacheOptions( const cacheBasePath = resolve(worspaceRoot, path); + const cachePath = projectName + ? join(cacheBasePath, VERSION, projectName) + : join(cacheBasePath, VERSION); + return { enabled: cacheEnabled, basePath: cacheBasePath, - path: join(cacheBasePath, VERSION), + path: cachePath, }; }