diff --git a/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts b/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts index cd2cd43d777c..8dd8915c874f 100644 --- a/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts +++ b/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts @@ -35,8 +35,7 @@ async function _renderUniversal( ): Promise { // Get browser target options. const browserTarget = targetFromTargetString(options.browserTarget); - const rawBrowserOptions = (await context.getTargetOptions(browserTarget)) as JsonObject & - BrowserBuilderSchema; + const rawBrowserOptions = await context.getTargetOptions(browserTarget); const browserBuilderName = await context.getBuilderNameForTarget(browserTarget); const browserOptions = await context.validateOptions( rawBrowserOptions, diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts index 267c923d18b1..1adc8fa57e3f 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/vite-server.ts @@ -39,6 +39,12 @@ interface OutputFileRecord { servable: boolean; } +/** + * Build options that are also present on the dev server but are only passed + * to the build. + */ +const CONVENIENCE_BUILD_OPTIONS = ['watch', 'poll', 'verbose'] as const; + // eslint-disable-next-line max-lines-per-function export async function* serveWithVite( serverOptions: NormalizedDevServerOptions, @@ -53,22 +59,23 @@ export async function* serveWithVite( }, ): AsyncIterableIterator { // Get the browser configuration from the target name. - const rawBrowserOptions = (await context.getTargetOptions( - serverOptions.buildTarget, - )) as json.JsonObject & BrowserBuilderOptions; + const rawBrowserOptions = await context.getTargetOptions(serverOptions.buildTarget); // Deploy url is not used in the dev-server. delete rawBrowserOptions.deployUrl; - const browserOptions = (await context.validateOptions( - { - ...rawBrowserOptions, - watch: serverOptions.watch, - poll: serverOptions.poll, - verbose: serverOptions.verbose, - } as json.JsonObject & BrowserBuilderOptions, + // Copy convenience options to build + for (const optionName of CONVENIENCE_BUILD_OPTIONS) { + const optionValue = serverOptions[optionName]; + if (optionValue !== undefined) { + rawBrowserOptions[optionName] = optionValue; + } + } + + const browserOptions = await context.validateOptions( + rawBrowserOptions, builderName, - )) as json.JsonObject & BrowserBuilderOptions; + ); if (browserOptions.prerender || browserOptions.ssr) { // Disable prerendering if enabled and force SSR. diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/webpack-server.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/webpack-server.ts index 7ba2ea697175..0e73bf41adaf 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/webpack-server.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/webpack-server.ts @@ -85,9 +85,7 @@ export function serveWebpackBrowser( } // Get the browser configuration from the target name. - const rawBrowserOptions = (await context.getTargetOptions( - options.buildTarget, - )) as json.JsonObject & BrowserBuilderSchema; + const rawBrowserOptions = await context.getTargetOptions(options.buildTarget); if (rawBrowserOptions.outputHashing && rawBrowserOptions.outputHashing !== OutputHashing.None) { // Disable output hashing for dev build as this can cause memory leaks diff --git a/packages/angular_devkit/build_angular/src/builders/prerender/index.ts b/packages/angular_devkit/build_angular/src/builders/prerender/index.ts index be939b61168f..3098a4996e73 100644 --- a/packages/angular_devkit/build_angular/src/builders/prerender/index.ts +++ b/packages/angular_devkit/build_angular/src/builders/prerender/index.ts @@ -12,7 +12,6 @@ import { createBuilder, targetFromTargetString, } from '@angular-devkit/architect'; -import { json } from '@angular-devkit/core'; import * as fs from 'fs'; import { readFile } from 'node:fs/promises'; import ora from 'ora'; @@ -30,7 +29,7 @@ import type { RenderOptions, RenderResult } from './render-worker'; import { RoutesExtractorWorkerData } from './routes-extractor-worker'; import { Schema } from './schema'; -type PrerenderBuilderOptions = Schema & json.JsonObject; +type PrerenderBuilderOptions = Schema; type PrerenderBuilderOutput = BuilderOutput; class RoutesSet extends Set { diff --git a/packages/angular_devkit/build_angular/src/utils/normalize-cache.ts b/packages/angular_devkit/build_angular/src/utils/normalize-cache.ts index 7d8c10053b6a..36f49486bc37 100644 --- a/packages/angular_devkit/build_angular/src/utils/normalize-cache.ts +++ b/packages/angular_devkit/build_angular/src/utils/normalize-cache.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import { json } from '@angular-devkit/core'; import { join, resolve } from 'path'; import { VERSION } from './package-version'; @@ -25,14 +24,22 @@ interface CacheMetadata { path?: string; } +function hasCacheMetadata(value: unknown): value is { cli: { cache: CacheMetadata } } { + return ( + !!value && + typeof value === 'object' && + 'cli' in value && + !!value['cli'] && + typeof value['cli'] === 'object' && + 'cache' in value['cli'] + ); +} + export function normalizeCacheOptions( - metadata: json.JsonObject, + projectMetadata: unknown, worspaceRoot: string, ): NormalizedCachedOptions { - const cacheMetadata: CacheMetadata = - json.isJsonObject(metadata.cli) && json.isJsonObject(metadata.cli.cache) - ? metadata.cli.cache - : {}; + const cacheMetadata = hasCacheMetadata(projectMetadata) ? projectMetadata.cli.cache : {}; const { enabled = true, environment = 'local', path = '.angular/cache' } = cacheMetadata; const isCI = process.env['CI'] === '1' || process.env['CI']?.toLowerCase() === 'true';