From 1682c609385ebadab20f047db070e17a60b2e0da Mon Sep 17 00:00:00 2001 From: Andrew Kushnir Date: Thu, 15 Aug 2024 18:37:53 -0700 Subject: [PATCH] docs: add eager to lazy route migration (#57421) PR Close #57421 --- adev/src/app/sub-navigation-data.ts | 5 ++ .../reference/migrations/inject-function.md | 15 +++- .../content/reference/migrations/overview.md | 5 +- .../migrations/route-lazy-loading.md | 75 +++++++++++++++++++ 4 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 adev/src/content/reference/migrations/route-lazy-loading.md diff --git a/adev/src/app/sub-navigation-data.ts b/adev/src/app/sub-navigation-data.ts index f0aab299260..c51bf125666 100644 --- a/adev/src/app/sub-navigation-data.ts +++ b/adev/src/app/sub-navigation-data.ts @@ -1472,6 +1472,11 @@ const REFERENCE_SUB_NAVIGATION_DATA: NavigationItem[] = [ path: 'reference/migrations/inject-function', contentPath: 'reference/migrations/inject-function', }, + { + label: 'Lazy-loaded routes', + path: 'reference/migrations/route-lazy-loading', + contentPath: 'reference/migrations/route-lazy-loading', + }, ], }, { diff --git a/adev/src/content/reference/migrations/inject-function.md b/adev/src/content/reference/migrations/inject-function.md index 3f04f57a59f..ba1b437fc45 100644 --- a/adev/src/content/reference/migrations/inject-function.md +++ b/adev/src/content/reference/migrations/inject-function.md @@ -13,6 +13,7 @@ ng generate @angular/core:inject #### Before + import { Component, Inject, Optional } from '@angular/core'; import { MyService } from './service'; @@ -20,11 +21,14 @@ import { DI_TOKEN } from './token'; @Component() export class MyComp { - constructor(private service: MyService, @Inject(TOKEN) @Optional() readonly token: string) {} + constructor( + private service: MyService, + @Inject(TOKEN) @Optional() readonly token: string) {} } #### After + import { Component, inject } from '@angular/core'; import { MyService } from './service'; @@ -38,19 +42,23 @@ export class MyComp { ## Migration options + The migration includes several options to customize its output. ### `path` + Determines which sub-path in your project should be migrated. Pass in `.` or leave it blank to migrate the entire directory. ### `migrateAbstractClasses` + Angular doesn't validate that parameters of abstract classes are injectable. This means that the migration can't reliably migrate them to `inject` without risking breakages which is why they're disabled by default. Enable this option if you want abstract classes to be migrated, but note that you may have to **fix some breakages manually**. ### `backwardsCompatibleConstructors` + By default the migration tries to clean up the code as much as it can, which includes deleting parameters from the constructor, or even the entire constructor if it doesn't include any code. In some cases this can lead to compilation errors when classes with Angular decorators inherit from @@ -58,6 +66,7 @@ other classes with Angular decorators. If you enable this option, the migration additional constructor signature to keep it backwards compatible, at the expense of more code. #### Before + import { Component } from '@angular/core'; import { MyService } from './service'; @@ -69,6 +78,7 @@ export class MyComp { #### After + import { Component } from '@angular/core'; import { MyService } from './service'; @@ -85,6 +95,7 @@ export class MyComp { ### `nonNullableOptional` + If injection fails for a parameter with the `@Optional` decorator, Angular returns `null` which means that the real type of any `@Optional` parameter will be `| null`. However, because decorators cannot influence their types, there is a lot of existing code whose type is incorrect. The type is @@ -96,6 +107,7 @@ at the expense of potentially hiding type errors. because the code that depends on them likely already accounts for their nullability. #### Before + import { Component, Inject, Optional } from '@angular/core'; import { TOKEN_ONE, TOKEN_TWO } from './token'; @@ -109,6 +121,7 @@ export class MyComp { #### After + import { Component, inject } from '@angular/core'; import { TOKEN_ONE, TOKEN_TWO } from './token'; diff --git a/adev/src/content/reference/migrations/overview.md b/adev/src/content/reference/migrations/overview.md index 48ec0e9673a..a5eaa805f70 100644 --- a/adev/src/content/reference/migrations/overview.md +++ b/adev/src/content/reference/migrations/overview.md @@ -7,9 +7,12 @@ Learn about how you can migrate your existing angular project to the latest feat Standalone components provide a simplified way to build Angular applications. Standalone components specify their dependencies directly instead of getting them through NgModules. - Control Flow Syntax is available with Angular 17 release and allows you to use more ergonomic syntax which is close to javascript, better type checking and lazy load part of the component. It replaces the need to imports CommonModule to use functionalities like `*ngFor`, `*ngIf`. + Built-in Control Flow Syntax allows you to use more ergonomic syntax which is close to JavaScript and has better type checking. It replaces the need to import `CommonModule` to use functionality like `*ngFor`, `*ngIf` and `*ngSwitch`. Angular's `inject` function offers more accurate types and better compatibility with standard decorators, compared to constructor-based injection. + + Convert eagerly loaded component routes to lazy loaded ones. This allows the build process to split production bundles into smaller chunks, to load less JavaScript at initial page load. + diff --git a/adev/src/content/reference/migrations/route-lazy-loading.md b/adev/src/content/reference/migrations/route-lazy-loading.md new file mode 100644 index 00000000000..7c084df3f60 --- /dev/null +++ b/adev/src/content/reference/migrations/route-lazy-loading.md @@ -0,0 +1,75 @@ +# Migration to lazy-loaded routes + +This schematic helps developers to convert eagerly loaded component routes to lazy loaded routes. This allows the build process to split the production bundle into smaller chunks, to avoid big JS bundle that includes all routes, which negatively affects initial page load of an application. + +Run the schematic using the following command: + + + +ng generate @angular/core:route-lazy-loading + + + +### `path` config option + +By default, migration will go over the entire application. If you want to apply this migration to a subset of the files, you can pass the path argument as shown below: + + + +ng generate @angular/core:route-lazy-loading --path src/app/sub-component + + + +The value of the path parameter is a relative path within the project. + +### How does it work? + +The schematic will attempt to find all the places where the application routes as defined: + +- `RouterModule.forRoot` and `RouterModule.forChild` +- `Router.resetConfig` +- `provideRouter` +- `provideRoutes` +- variables of type `Routes` or `Route[]` (e.g. `const routes: Routes = [{...}]`) + +The migration will check all the components in the routes, check if they are standalone and eagerly loaded, and if so, it will convert them to lazy loaded routes. + +#### Before + + +// app.module.ts +import { HomeComponent } from './home/home.component'; + +@NgModule({ + imports: [ + RouterModule.forRoot([ + { + path: 'home', + // HomeComponent is standalone and eagerly loaded + component: HomeComponent, + }, + ]), + ], +}) +export class AppModule {} + + +#### After + + +// app.module.ts +@NgModule({ + imports: [ + RouterModule.forRoot([ + { + path: 'home', + // ↓ HomeComponent is now lazy loaded + loadComponent: () => import('./home/home.component').then(m => m.HomeComponent), + }, + ]), + ], +}) +export class AppModule {} + + +This migration will also collect information about all the components declared in NgModules and output the list of routes that use them (including corresponding location of the file). Consider making those components standalone and run this migration again. You can use an existing migration (see https://angular.dev/reference/migrations/standalone) to convert those components to standalone.