Upgrading @angular/compiler 17 to 18
Breaking17.3.12 → 18.2.14Breaking47Security1Platform3Deprecated10New39Changed6Fixed236Other4
BreakingUpgrade verdict
39 breaking changes and 3 platform requirement changes and a security fix.
In plain terms
- Server-side apps must now pass a bootstrap context into `bootstrapApplication` instead of relying on a shared global platform.
- Tests using fakeAsync will now run any leftover timers when the test function finishes, unless you opt out.
- A long-deprecated animation helper method is gone, so any code still calling it will stop working.
- Two deprecated platform-check functions are removed, so code using them must be updated.
Must act Top 5 of 53 that need code or config changes
Node.js requirement changed in 18.1.0-next.1: ^18.13.0 || >=20.9.0 → ^18.19.1 || ^20.11.1 || >=22.0.0.
What you must change
Breaking39
Introduces
BootstrapContext for server bootstrapping, removing reliance on a global platform injector.BootstrapContextbootstrapApplicationgetPlatform()destroyPlatform()fakeAsync now flushes pending timers at the end of the given function by default.
fakeAsyncRemoves deprecated
matchesElement from AnimationDriver.AnimationDrivermatchesElementRemoves deprecated
isPlatformWorkerApp and isPlatformWorkerUi APIs.isPlatformWorkerAppisPlatformWorkerUiRemoves support for unassignable expressions in two-way bindings.
Removes deprecated transfer state APIs.
StateKeyTransferStatemakeStateKeyRemoves deprecated Testability methods.
TestabilityRemoves the unused
RESOURCE_CACHE_PROVIDER API from platform-browser-dynamic.RESOURCE_CACHE_PROVIDERRemoves the deprecated
platformDynamicServer API from platform-server.platformDynamicServerRemoves the deprecated
ServerTransferStateModule API from platform-server.ServerTransferStateModuleRemoves deprecated useAbsoluteUrl and baseUrl from PlatformConfig; provide an absolute url instead.
useAbsoluteUrlbaseUrlPlatformConfigurlRemoves legacy URL handling logic from platform-server.
ComponentFixture autoDetect no longer refreshes host view for dirty-less OnPush components.ComponentFixtureautoDetectOnPushmarkForCheckChangeDetectionStrategy.DefaultRemoves Testability methods increasePendingRequestCount, decreasePendingRequestCount and getPendingRequestCount.
increasePendingRequestCountdecreasePendingRequestCountgetPendingRequestCountHTTP transfer cache now prevents caching of requests requiring authorization by default; opt out with includeRequestsWithAuthHeaders.
withHttpTransferCacheincludeRequestsWithAuthHeadersRemoves deprecated StateKey, TransferState and makeStateKey from @angular/platform-browser; use them from @angular/core.
StateKeyTransferStatemakeStateKey@angular/platform-browser@angular/coreRemoves unused RESOURCE_CACHE_PROVIDER APIs from @angular/platform-browser-dynamic.
RESOURCE_CACHE_PROVIDERRemoves deprecated platformDynamicServer; import @angular/compiler and use platformServer instead.
platformDynamicServerplatformServer@angular/compilerRemoves deprecated ServerTransferStateModule; TransferState can be used without providing this module.
ServerTransferStateModuleTransferStateRemoves legacy Node.js URL parsing from ServerPlatformLocation, changing pathname and port handling.
ServerPlatformLocationpathnameportExcludes authenticated HTTP requests from caching by default; opt out with
includeRequestsWithAuthHeaders.withHttpTransferCacheincludeRequestsWithAuthHeadersAngular no longer ignores changes that happen outside the zone, so change detection runs for them.
provideZoneChangeDetectionNgZoneSchedulingMode.NgZoneOnlyBootstrapOptionsbootstrapApplicationbootstrapModuleRemoves deprecated Testability methods increasePendingRequestCount, decreasePendingRequestCount and getPendingRequestCount.
increasePendingRequestCountdecreasePendingRequestCountgetPendingRequestCountRedesigns the afterRender and afterNextRender phases API.
afterRenderafterNextRenderComponentFixture.whenStable now matches ApplicationRef.isStable, including router navigations and HttpClient requests, and isStable is always asynchronous.
ComponentFixture.whenStableApplicationRef.isStableComponentFixture.isStableHttpTestingController.verify()HttpClientfixture.whenStableModifies EventType from an enum to an object.
EventTypeAngular only supports writable expressions inside two-way bindings.
OnPush root views must be marked dirty for their host bindings to refresh.OnPushChange detection continues refreshing views attached to ApplicationRef still marked for check, which can cause infinite loops surfaced as NG0103.
ApplicationRefChangeDetectorRef.detectChangesNG0103Removes the async test helper; use waitForAsync instead.
asyncwaitForAsyncChange detection timing with event or run coalescing in NgZone is now the first of setTimeout or requestAnimationFrame.
NgZonesetTimeoutrequestAnimationFrameafterNextRenderNewly created or reattached views marked for check during change detection are now guaranteed to refresh in the same cycle.
ExpressionChangedAfterItHasBeenCheckedErrorRouter guards can now return RedirectCommand for redirects in addition to UrlTree, requiring Route type adjustments.
RedirectCommandUrlTreeRouteAllows Route.redirectTo to be a function in addition to a string, so code expecting only a string must be adjusted.
Route.redirectToRouteGuard redirects via UrlTree now use replaceUrl when the initial navigation used replaceUrl; return a RedirectCommand to customize options.
UrlTreereplaceUrlNavigationBehaviorOptionsRedirectCommandProviders for routed components come only from the route injector hierarchy and never inherit from RouterOutlet.
RouterOutletNgModuleprovidersCompletes the removal of the deprecated
async function; use waitForAsync instead.asyncwaitForAsyncAngular ensures change detection runs even when state updates originate outside the zone, which may add change detection rounds in tests.
provideZoneChangeDetectionNgZoneSchedulingMode.NgZoneOnlyTestBedbootstrapApplicationBootstrapOptionsbootstrapModuleComponentFixture.autoDetect now runs change detection within ApplicationRef.tick, changing refresh order in tests.
ComponentFixture.autoDetectApplicationRef.tickSecurity1
Addresses Trusted Types violations in @angular/upgrade.
@angular/upgradePlatform3
Adds support for TypeScript 5.5.
Drops support for TypeScript versions older than 5.4.
Angular no longer supports TypeScript versions older than 5.4.
Deprecations to plan for
Deprecated10
Deprecates the ignoreChangesOutsideZone option.
ignoreChangesOutsideZoneAdds back the phase flag option as a deprecated API.
Deprecates the Local Data API functions.
Deprecates the @Component.interpolation property.
@Component.interpolationDeprecates HttpClientModule and related modules.
HttpClientModuleDeprecates common locale helper functions including getCurrencySymbol, getLocaleCurrencyCode, getLocaleDateFormat and related APIs.
getCurrencySymbolgetLocaleCurrencyCodegetLocaleCurrencyNamegetLocaleCurrencySymbolgetLocaleDateFormatgetLocaleDateTimeFormatgetLocaleDayNamesgetLocaleDayPeriodsDeprecates @Component.interpolation; use Angular's delimiters instead.
@Component.interpolationDeprecates HttpClientModule, HttpClientXsrfModule and HttpClientJsonpModule, which can be replaced by provider functions.
HttpClientModuleHttpClientXsrfModuleHttpClientJsonpModuleDeprecates
@Component.interpolation in favor of Angular's delimiters.@Component.interpolationDeprecates
HttpClientModule and related modules in favor of provider functions.HttpClientModuleHttpClientXsrfModuleHttpClientJsonpModuleAPI changes
Generated by DepDelta from published .d.ts files. Not mixed with prose notes.
- removed:
const enum BindingType - removed:
const enum ParsedEventType - removed:
interface R3DeferBlockMetadata - removed:
interface R3DeferBlockTemplateDependency - removed:
property R3ComponentMetadata.deferBlockDepsEmitMode: DeferBlockDepsEmitMode - removed:
property R3ComponentMetadata.deferBlocks: Map<t.DeferredBlock, R3DeferBlockMetadata> - removed:
property R3ComponentMetadata.deferrableDeclToImportDecl: Map<outputAst.Expression, outputAst.Expression> - removed:
property R3ComponentMetadata.deferrableTypes: Map<string, { importPath: string; isDefaultImport: boolean }> - removed:
property R3ComponentMetadata.useTemplatePipeline: boolean - removed:
property R3DeferBlockMetadata.deps: R3DeferBlockTemplateDependency[] - removed:
property R3DeferBlockMetadata.triggerElements: Map<t.DeferredTrigger, t.Element | null> - removed:
property R3DeferBlockTemplateDependency.importPath: string | null - removed:
property R3DeferBlockTemplateDependency.isDefaultImport: boolean - removed:
property R3DeferBlockTemplateDependency.isDeferrable: boolean - removed:
property R3DeferBlockTemplateDependency.symbolName: string - removed:
property R3DeferBlockTemplateDependency.type: outputAst.WrappedNodeExpr<unknown> - removed:
property R3HostMetadata.useTemplatePipeline: boolean - removed:
static property R3Identifiers.InputFlags: outputAst.ExternalReference - changed:
constructor ExternalReference(moduleName: string | null, name: string | null, runtime?: any) → constructor ExternalReference(moduleName: string | null, name: string | null, runtime?: any | null) - changed:
constructor FunctionExpr(params: FnParam[], statements: Statement[], type?: Type | null, sourceSpan?: ParseSourceSpan | null, name?: string | null | undefined) → constructor FunctionExpr(params: FnParam[], statements: Statement[], type?: Type | null, sourceSpan?: ParseSourceSpan | null, name?: (string | null) | undefined) - changed:
constructor MessageBundle(_htmlParser: HtmlParser, _implicitTags: string[], _implicitAttrs: { [k: string]: string[] }, _locale?: string | null) → constructor MessageBundle(_htmlParser: HtmlParser, _implicitTags: string[], _implicitAttrs: { [k: string]: string[] }, _locale?: string | null, _preserveWhitespace?: boolean) - changed:
constructor TmplAstContent(selector: string, attributes: TmplAstTextAttribute[], sourceSpan: ParseSourceSpan, i18n?: I18nMeta_2 | undefined) → constructor TmplAstContent(selector: string, attributes: TmplAstTextAttribute[], children: TmplAstNode[], sourceSpan: ParseSourceSpan, i18n?: I18nMeta_2 | undefined) - changed:
constructor TmplAstForLoopBlock(item: TmplAstVariable, expression: ASTWithSource, trackBy: ASTWithSource, trackKeywordSpan: ParseSourceSpan, contextVariables: ForLoopBlockContext, children: TmplAstNode[], empty: TmplAstForLoopBlockEmpty | null, sourceSpan: ParseSourceSpan, mainBlockSpan: ParseSourceSpan, startSourceSpan: ParseSourceSpan, endSourceSpan: ParseSourceSpan | null, nameSpan: ParseSourc… → constructor TmplAstForLoopBlock(item: TmplAstVariable, expression: ASTWithSource, trackBy: ASTWithSource, trackKeywordSpan: ParseSourceSpan, contextVariables: TmplAstVariable[], children: TmplAstNode[], empty: TmplAstForLoopBlockEmpty | null, sourceSpan: ParseSourceSpan, mainBlockSpan: ParseSourceSpan, startSourceSpan: ParseSourceSpan, endSourceSpan: ParseSourceSpan | null, nameSpan: ParseSourceS… - changed:
function compileClassMetadata(metadata: R3ClassMetadata): outputAst.Expression → function compileClassMetadata(metadata: R3ClassMetadata): outputAst.InvokeFunctionExpr - changed:
function compileComponentClassMetadata(metadata: R3ClassMetadata, deferrableTypes: Map<string, { importPath: string; isDefaultImport: boolean }> | null): outputAst.Expression → function compileComponentClassMetadata(metadata: R3ClassMetadata, dependencies: R3DeferPerComponentDependency[] | null): outputAst.Expression - changed:
function makeBindingParser(interpolationConfig?: InterpolationConfig): BindingParser → function makeBindingParser(interpolationConfig?: InterpolationConfig, allowInvalidAssignmentEvents?: boolean): BindingParser - changed:
member LexerTokenType.EOF = 29 → member LexerTokenType.EOF = 33 - changed:
method BoundTarget.getDefinitionNodeOfSymbol(symbol: TmplAstReference | TmplAstVariable): ScopedNode | null → method BoundTarget.getDefinitionNodeOfSymbol(symbol: TemplateEntity): ScopedNode | null - changed:
method BoundTarget.getEntitiesInScope(node: ScopedNode | null): ReadonlySet<TmplAstReference | TmplAstVariable> → method BoundTarget.getEntitiesInScope(node: ScopedNode | null): ReadonlySet<TemplateEntity> - changed:
method BoundTarget.getExpressionTarget(expr: AST): TmplAstReference | TmplAstVariable | null → method BoundTarget.getExpressionTarget(expr: AST): TemplateEntity | null - changed:
method ConstantPool.getSharedFunctionReference(fn: outputAst.FunctionExpr | outputAst.ArrowFunctionExpr, prefix: string, useUniqueName?: boolean): outputAst.Expression → method ConstantPool.getSharedFunctionReference(fn: outputAst.Expression, prefix: string, useUniqueName?: boolean): outputAst.Expression - changed:
method MessageBundle.updateFromTemplate(html: string, url: string, interpolationConfig: InterpolationConfig): ParseError[] → method MessageBundle.updateFromTemplate(source: string, url: string, interpolationConfig: InterpolationConfig): ParseError[] - changed:
method R3BoundTarget.getDefinitionNodeOfSymbol(symbol: TmplAstReference | TmplAstVariable): ScopedNode | null → method R3BoundTarget.getDefinitionNodeOfSymbol(symbol: TemplateEntity): ScopedNode | null - changed:
method R3BoundTarget.getEntitiesInScope(node: ScopedNode | null): ReadonlySet<TmplAstReference | TmplAstVariable> → method R3BoundTarget.getEntitiesInScope(node: ScopedNode | null): ReadonlySet<TemplateEntity> - changed:
method R3BoundTarget.getExpressionTarget(expr: AST): TmplAstReference | TmplAstVariable | null → method R3BoundTarget.getExpressionTarget(expr: AST): TemplateEntity | null - changed:
property ExternalReference.runtime?: any → property ExternalReference.runtime?: any | null - changed:
property FunctionExpr.name?: string | null | undefined → property FunctionExpr.name?: (string | null) | undefined - changed:
property TmplAstForLoopBlock.contextVariables: ForLoopBlockContext → property TmplAstForLoopBlock.contextVariables: TmplAstVariable[] - changed:
type LiteralMapKey = { key: string; quoted: boolean } → type LiteralMapKey = { key: string; quoted: boolean; isShorthandInitialized?: boolean } - added:
class LetDeclaration implements BaseNode - added:
class TmplAstLetDeclaration implements TmplAstNode - added:
constructor LetDeclaration(name: string, value: string, sourceSpan: ParseSourceSpan, nameSpan: ParseSourceSpan, valueSpan: ParseSourceSpan) - added:
constructor TmplAstLetDeclaration(name: string, value: AST, sourceSpan: ParseSourceSpan, nameSpan: ParseSourceSpan, valueSpan: ParseSourceSpan) - added:
constructor Xmb(preservePlaceholders?: boolean) - added:
enum BindingType - added:
enum ParsedEventType - added:
function compileComponentDeclareClassMetadata(metadata: R3ClassMetadata, dependencies: R3DeferPerComponentDependency[] | null): outputAst.Expression - added:
function compileDeferResolverFunction(meta: R3DeferResolverFunctionMetadata): outputAst.ArrowFunctionExpr - added:
function compileOpaqueAsyncClassMetadata(metadata: R3ClassMetadata, deferResolver: outputAst.Expression, deferredDependencyNames: string[]): outputAst.Expression - added:
function findMatchingDirectivesAndPipes(template: string, directiveSelectors: string[]): { directives: { regular: string[]; deferCandidates: string[] }; pipes: { regular: string[]; deferCandidates: string[] } } - added:
interface R3DeclareClassMetadataAsync extends R3PartialDeclaration - added:
interface R3DeferPerBlockDependency - added:
interface R3DeferPerComponentDependency - added:
member LexerTokenType.INCOMPLETE_LET = 32 - added:
member LexerTokenType.LET_END = 31 - added:
member LexerTokenType.LET_START = 29 - added:
member LexerTokenType.LET_VALUE = 30 - added:
method LetDeclaration.visit(visitor: Visitor, context: any): any - added:
method RecursiveVisitor.visitLetDeclaration(decl: LetDeclaration, context: any): void - added:
method TmplAstLetDeclaration.visit<Result>(visitor: TmplAstVisitor<Result>): Result - added:
method TmplAstRecursiveVisitor.visitLetDeclaration(decl: TmplAstLetDeclaration): void - added:
method TmplAstVisitor.visitLetDeclaration(decl: TmplAstLetDeclaration): Result - added:
method Visitor.visitLetDeclaration(decl: LetDeclaration, context: any): any - added:
property LetDeclaration.name: string - added:
property LetDeclaration.sourceSpan: ParseSourceSpan - added:
property LetDeclaration.value: string - added:
property LetDeclaration.valueSpan: ParseSourceSpan - added:
property ParseTemplateOptions.allowInvalidAssignmentEvents?: boolean - added:
property ParseTemplateOptions.enableLetSyntax?: boolean - added:
property ParseTemplateOptions.preserveSignificantWhitespace?: boolean - added:
property R3ComponentMetadata.defer: R3ComponentDeferMetadata - added:
property R3DeclareClassMetadataAsync.resolveDeferredDeps: outputAst.Expression - added:
property R3DeclareClassMetadataAsync.resolveMetadata: outputAst.Expression - added:
property R3DeclareComponentMetadata.deferBlockDependencies?: outputAst.Expression[] - added:
property R3DeferPerBlockDependency.importPath: string | null - added:
property R3DeferPerBlockDependency.isDefaultImport: boolean - added:
property R3DeferPerBlockDependency.isDeferrable: boolean - added:
property R3DeferPerBlockDependency.symbolName: string - added:
property R3DeferPerBlockDependency.typeReference: outputAst.Expression - added:
property R3DeferPerComponentDependency.importPath: string - added:
property R3DeferPerComponentDependency.isDefaultImport: boolean - added:
property R3DeferPerComponentDependency.symbolName: string - added:
property TmplAstContent.children: TmplAstNode[] - added:
property TmplAstLetDeclaration.name: string - added:
property TmplAstLetDeclaration.nameSpan: ParseSourceSpan - added:
property TmplAstLetDeclaration.sourceSpan: ParseSourceSpan - added:
property TmplAstLetDeclaration.value: AST - added:
property TmplAstLetDeclaration.valueSpan: ParseSourceSpan - added:
readonly property LetDeclaration.nameSpan: ParseSourceSpan - added:
static property R3Identifiers.declareClassMetadataAsync: outputAst.ExternalReference - added:
static property R3Identifiers.declareLet: outputAst.ExternalReference - added:
static property R3Identifiers.readContextLet: outputAst.ExternalReference - added:
static property R3Identifiers.storeLet: outputAst.ExternalReference - added:
type R3ComponentDeferMetadata = { mode: DeferBlockDepsEmitMode.PerBlock; blocks: Map<t.DeferredBlock, outputAst.Expression | null> } | { mode: DeferBlockDepsEmitMode.PerComponent; dependencie… - added:
type R3DeferResolverFunctionMetadata = { mode: DeferBlockDepsEmitMode.PerBlock; dependencies: R3DeferPerBlockDependency[] } | { mode: DeferBlockDepsEmitMode.PerComponent; dependencies: R3DeferPerCom… - added:
type TemplateEntity = TmplAstReference | TmplAstVariable | TmplAstLetDeclaration