docs: modify lazy-load module instructions for new cli flag (#32588)
PR Close #32588
This commit is contained in:
parent
0a0489d3d0
commit
5cf597249c
|
@ -5,13 +5,13 @@
|
||||||
By default, NgModules are eagerly loaded, which means that as soon as the app loads, so do all the NgModules, whether or not they are immediately necessary. For large apps with lots of routes, consider lazy loading—a design pattern that loads NgModules as needed. Lazy loading helps keep initial
|
By default, NgModules are eagerly loaded, which means that as soon as the app loads, so do all the NgModules, whether or not they are immediately necessary. For large apps with lots of routes, consider lazy loading—a design pattern that loads NgModules as needed. Lazy loading helps keep initial
|
||||||
bundle sizes smaller, which in turn helps decrease load times.
|
bundle sizes smaller, which in turn helps decrease load times.
|
||||||
|
|
||||||
For the final sample app with two lazy loaded modules that this page describes, see the
|
For the final sample app with two lazy-loaded modules that this page describes, see the
|
||||||
<live-example></live-example>.
|
<live-example></live-example>.
|
||||||
|
|
||||||
There are three main steps to setting up a lazy loaded feature module:
|
There are three main steps to setting up a lazy-loaded feature module:
|
||||||
|
|
||||||
1. Create the feature module.
|
1. Create the feature module with the CLI, using the `--route` flag.
|
||||||
1. Create the feature module’s routing module.
|
1. Create the feature module’s component.
|
||||||
1. Configure the routes.
|
1. Configure the routes.
|
||||||
|
|
||||||
## Set up an app
|
## Set up an app
|
||||||
|
@ -21,9 +21,9 @@ create one with the CLI. If you do already have an app, skip to
|
||||||
[Configure the routes](#config-routes). Enter the following command
|
[Configure the routes](#config-routes). Enter the following command
|
||||||
where `customer-app` is the name of your app:
|
where `customer-app` is the name of your app:
|
||||||
|
|
||||||
```sh
|
<code-example language="bash">
|
||||||
ng new customer-app --routing
|
ng new customer-app --routing
|
||||||
```
|
</code-example>
|
||||||
|
|
||||||
This creates an app called `customer-app` and the `--routing` flag
|
This creates an app called `customer-app` and the `--routing` flag
|
||||||
generates a file called `app-routing.module.ts`, which is one of
|
generates a file called `app-routing.module.ts`, which is one of
|
||||||
|
@ -32,71 +32,63 @@ Navigate into the project by issuing the command `cd customer-app`.
|
||||||
|
|
||||||
## Create a feature module with routing
|
## Create a feature module with routing
|
||||||
|
|
||||||
Next, you’ll need a feature module to route to. To make one, enter
|
Next, you’ll need a feature module with a component to route to.
|
||||||
the following command at the terminal window prompt where `customers` is the name of the module:
|
To make one, enter the following command in the terminal, where `customers` is the name of the feature module, and `customer-list` is the route path for loading the `customers` component:
|
||||||
|
|
||||||
```sh
|
<code-example language="bash">
|
||||||
ng generate module customers --routing
|
ng generate module customers --route customer-list --module app.module
|
||||||
```
|
</code-example>
|
||||||
|
|
||||||
This creates a customers folder with two files inside; `CustomersModule`
|
This creates a `customers` folder with the new lazy-loadable module `CustomersModule` defined in the file `customers.module.ts`. The command automatically adds the `CustomerComponent` to the new feature module.
|
||||||
and `CustomersRoutingModule`. `CustomersModule` will act as the gatekeeper
|
|
||||||
for anything that concerns customers. `CustomersRoutingModule` will handle
|
|
||||||
any customer-related routing. This keeps the app’s structure organized as
|
|
||||||
the app grows and allows you to reuse this module while easily keeping its routing intact.
|
|
||||||
|
|
||||||
The CLI imports the `CustomersRoutingModule` into the `CustomersModule` by
|
Because the new module is meant to be lazy-loaded, the command does NOT add a reference for the new feature module to the root application's module file, `app.module.ts`.
|
||||||
adding a JavaScript import statement at the top of the file and adding
|
Instead, it adds the declared route, `customer-list` to the `Routes` array declared in the module provided as the `--module` option.
|
||||||
`CustomersRoutingModule` to the `@NgModule` `imports` array.
|
|
||||||
|
|
||||||
## Add a component to the feature module
|
<code-example language="typescript" header="src/app/app-routing.module.ts">
|
||||||
|
const routes: Routes = [
|
||||||
|
{ path: 'customer-list',
|
||||||
|
loadChildren: () => import('./customers/customers.module').then(m => m.CustomersModule) }
|
||||||
|
];
|
||||||
|
</code-example>
|
||||||
|
|
||||||
In order to see the module being lazy loaded in the browser, create a component to render some HTML when the app loads `CustomersModule`. At the command line, enter the following:
|
Notice that the lazy-loading syntax uses `loadChildren` followed by a function that uses the browser's built-in `import('...')` syntax for dynamic imports.
|
||||||
|
The import path is the relative path to the module.
|
||||||
|
|
||||||
```sh
|
### Add another feature module
|
||||||
ng generate component customers/customer-list
|
|
||||||
```
|
|
||||||
|
|
||||||
This creates a folder inside of `customers` called `customer-list`
|
Use the same command to create a second lazy-loaded feature module with routing, along with its stub component.
|
||||||
with the four files that make up the component.
|
|
||||||
|
|
||||||
Just like with the routing module, the CLI imports the
|
<code-example language="bash">
|
||||||
`CustomerListComponent` into the `CustomersModule`.
|
ng generate module orders --route order-list --module app.module
|
||||||
|
</code-example>
|
||||||
|
|
||||||
|
This creates a new folder called `orders` containing an `OrdersModule` and `OrdersRoutingModule`, along with the new `OrderComponent` source files.
|
||||||
|
The `order-list` route is added to the `Routes` array in `app-routing.module.ts`, using the lazy-loading syntax.
|
||||||
|
|
||||||
## Add another feature module
|
<code-example language="typescript" header="src/app/app-routing.module.ts">
|
||||||
|
const routes: Routes = [
|
||||||
For another place to route to, create a second feature module with routing:
|
{ path: 'customer-list',
|
||||||
|
loadChildren: () => import('./customers/customers.module').then(m => m.CustomersModule) },
|
||||||
```sh
|
{ path: 'order-list',
|
||||||
ng generate module orders --routing
|
loadChildren: () => import('./orders/orders.module').then(m => m.OrdersModule) }
|
||||||
```
|
];
|
||||||
|
</code-example>
|
||||||
This makes a new folder called `orders` containing an `OrdersModule` and an `OrdersRoutingModule`.
|
|
||||||
|
|
||||||
Now, just like with the `CustomersModule`, give it some content:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
ng generate component orders/order-list
|
|
||||||
```
|
|
||||||
|
|
||||||
## Set up the UI
|
## Set up the UI
|
||||||
|
|
||||||
Though you can type the URL into the address bar, a nav
|
Though you can type the URL into the address bar, a navigation UI is easier for the user and more common.
|
||||||
is easier for the user and more common. Replace the default
|
Replace the default placeholder markup in `app.component.html` with a custom nav
|
||||||
placeholder markup in `app.component.html` with a custom nav
|
|
||||||
so you can easily navigate to your modules in the browser:
|
so you can easily navigate to your modules in the browser:
|
||||||
|
|
||||||
|
|
||||||
<code-example path="lazy-loading-ngmodules/src/app/app.component.html" region="app-component-template" header="src/app/app.component.html"></code-example>
|
<code-example path="lazy-loading-ngmodules/src/app/app.component.html" header="app.component.html" region="app-component-template" header="src/app/app.component.html"></code-example>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
To see your app in the browser so far, enter the following command in the terminal window:
|
To see your app in the browser so far, enter the following command in the terminal window:
|
||||||
|
|
||||||
```sh
|
<code-example language="bash">
|
||||||
ng serve
|
ng serve
|
||||||
```
|
</code-example>
|
||||||
|
|
||||||
Then go to `localhost:4200` where you should see “app works!” and three buttons.
|
Then go to `localhost:4200` where you should see “app works!” and three buttons.
|
||||||
|
|
||||||
|
@ -104,59 +96,42 @@ Then go to `localhost:4200` where you should see “app works!” and three butt
|
||||||
<img src="generated/images/guide/lazy-loading-ngmodules/three-buttons.png" width="300" alt="three buttons in the browser">
|
<img src="generated/images/guide/lazy-loading-ngmodules/three-buttons.png" width="300" alt="three buttons in the browser">
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
|
These buttons work, because the CLI automatically added the routes to the feature modules to the `routes` array in `app.module.ts`.
|
||||||
To make the buttons work, you need to configure the routing modules.
|
|
||||||
|
|
||||||
{@a config-routes}
|
{@a config-routes}
|
||||||
|
|
||||||
## Configure the routes
|
## Imports and route configuration
|
||||||
|
|
||||||
The two feature modules, `OrdersModule` and `CustomersModule`, have to be
|
|
||||||
wired up to the `AppRoutingModule` so the router knows about them. The structure is as follows:
|
|
||||||
|
|
||||||
<figure>
|
|
||||||
<img src="generated/images/guide/lazy-loading-ngmodules/lazy-load-relationship.jpg" width="400" alt="lazy loaded modules diagram">
|
|
||||||
</figure>
|
|
||||||
|
|
||||||
|
|
||||||
Each feature module acts as a doorway via the router. In the `AppRoutingModule`, you configure the routes to the feature modules, in this case `OrdersModule` and `CustomersModule`. This way, the router knows to go to the feature module. The feature module then connects the `AppRoutingModule` to the `CustomersRoutingModule` or the `OrdersRoutingModule`. Those routing modules tell the router where to go to load relevant components.
|
|
||||||
|
|
||||||
### Routes at the app level
|
|
||||||
|
|
||||||
|
The CLI automatically added each feature module to the routes map at the application level.
|
||||||
|
Finish this off by adding the default route.
|
||||||
In `AppRoutingModule`, update the `routes` array with the following:
|
In `AppRoutingModule`, update the `routes` array with the following:
|
||||||
|
|
||||||
|
<code-example path="lazy-loading-ngmodules/src/app/app-routing.module.ts" id="app-routing.module.ts" region="const-routes" header="src/app/app-routing.module.ts"></code-example>
|
||||||
|
|
||||||
<code-example path="lazy-loading-ngmodules/src/app/app-routing.module.ts" region="const-routes" header="src/app/app-routing.module.ts"></code-example>
|
The first two paths are the routes to the `CustomersModule` and the `OrdersModule`.
|
||||||
|
The final entry defines a default route. The empty path matches everything that doesn't match an earlier path.
|
||||||
|
|
||||||
|
|
||||||
The import statements stay the same. The first two paths are the routes to the `CustomersModule` and the `OrdersModule` respectively. Notice that the lazy loading syntax uses `loadChildren` followed by a function that uses the browser's built-in `import('...')` syntax for dynamic imports. The import path is the relative path to the module.
|
|
||||||
|
|
||||||
### Inside the feature module
|
### Inside the feature module
|
||||||
|
|
||||||
Next, take a look at `customers.module.ts`. If you’re using the CLI and following the steps outlined in this page, you don’t have to do anything here. The feature module is like a connector between the `AppRoutingModule` and the feature routing module. The `AppRoutingModule` imports the feature module, `CustomersModule`, and `CustomersModule` in turn imports the `CustomersRoutingModule`.
|
Next, take a look at `customers.module.ts`. If you’re using the CLI and following the steps outlined in this page, you don’t have to do anything here.
|
||||||
|
|
||||||
|
|
||||||
<code-example path="lazy-loading-ngmodules/src/app/customers/customers.module.ts" region="customers-module" header="src/app/customers/customers.module.ts"></code-example>
|
|
||||||
|
|
||||||
|
|
||||||
|
<code-example path="lazy-loading-ngmodules/src/app/customers/customers.module.ts" id="customers.module.ts" region="customers-module" header="src/app/customers/customers.module.ts"></code-example>
|
||||||
|
|
||||||
The `customers.module.ts` file imports the `CustomersRoutingModule` and `CustomerListComponent` so the `CustomersModule` class can have access to them. `CustomersRoutingModule` is then listed in the `@NgModule` `imports` array giving `CustomersModule` access to its own routing module, and `CustomerListComponent` is in the `declarations` array, which means `CustomerListComponent` belongs to the `CustomersModule`.
|
The `customers.module.ts` file imports the `CustomersRoutingModule` and `CustomerListComponent` so the `CustomersModule` class can have access to them. `CustomersRoutingModule` is then listed in the `@NgModule` `imports` array giving `CustomersModule` access to its own routing module, and `CustomerListComponent` is in the `declarations` array, which means `CustomerListComponent` belongs to the `CustomersModule`.
|
||||||
|
|
||||||
|
|
||||||
### Configure the feature module’s routes
|
The feature module has its own routing module, `customers-routing.module.ts`. The `AppRoutingModule` imports the feature module, `CustomersModule`, and `CustomersModule` in turn imports the `CustomersRoutingModule`.
|
||||||
|
|
||||||
The next step is in `customers-routing.module.ts`. First, import the component at the top of the file with the other JavaScript import statements. Then, add the route to `CustomerListComponent`.
|
The feature-specific routing module imports its own feature component, `CustomerListComponent`, along with the other JavaScript import statements. It also adds the route to its own component.
|
||||||
|
|
||||||
<code-example path="lazy-loading-ngmodules/src/app/customers/customers-routing.module.ts" region="customers-routing-module" header="src/app/customers/customers-routing.module.ts"></code-example>
|
|
||||||
|
|
||||||
|
<code-example path="lazy-loading-ngmodules/src/app/customers/customers-routing.module.ts" id="customers-routing.module.ts" region="customers-routing-module" header="src/app/customers/customers-routing.module.ts"></code-example>
|
||||||
|
|
||||||
Notice that the `path` is set to an empty string. This is because the path in `AppRoutingModule` is already set to `customers`, so this route in the `CustomersRoutingModule`, is already within the `customers` context. Every route in this routing module is a child route.
|
Notice that the `path` is set to an empty string. This is because the path in `AppRoutingModule` is already set to `customers`, so this route in the `CustomersRoutingModule`, is already within the `customers` context. Every route in this routing module is a child route.
|
||||||
|
|
||||||
Repeat this last step of importing the `OrdersListComponent` and configuring the Routes array for the `orders-routing.module.ts`:
|
The other feature module's routing module is configured similarly.
|
||||||
|
|
||||||
<code-example path="lazy-loading-ngmodules/src/app/orders/orders-routing.module.ts" region="orders-routing-module-detail" header="src/app/orders/orders-routing.module.ts (excerpt)"></code-example>
|
<code-example path="lazy-loading-ngmodules/src/app/orders/orders-routing.module.ts" id="orders-routing.module.ts" region="orders-routing-module-detail" header="src/app/orders/orders-routing.module.ts (excerpt)"></code-example>
|
||||||
|
|
||||||
Now, if you view the app in the browser, the three buttons take you to each module.
|
|
||||||
|
|
||||||
## Confirm it’s working
|
## Confirm it’s working
|
||||||
|
|
||||||
|
@ -167,7 +142,7 @@ You can check to see that a module is indeed being lazy loaded with the Chrome d
|
||||||
</figure>
|
</figure>
|
||||||
|
|
||||||
|
|
||||||
Click on the Orders or Customers button. If you see a chunk appear, you’ve wired everything up properly and the feature module is being lazy loaded. A chunk should appear for Orders and for Customers but will only appear once for each.
|
Click on the Orders or Customers button. If you see a chunk appear, everything is wired up properly and the feature module is being lazy loaded. A chunk should appear for Orders and for Customers but will only appear once for each.
|
||||||
|
|
||||||
|
|
||||||
<figure>
|
<figure>
|
||||||
|
@ -186,17 +161,17 @@ Then reload with `Cmd+r` or `Ctrl+r`, depending on your platform.
|
||||||
|
|
||||||
## `forRoot()` and `forChild()`
|
## `forRoot()` and `forChild()`
|
||||||
|
|
||||||
You might have noticed that the CLI adds `RouterModule.forRoot(routes)` to the `app-routing.module.ts` `imports` array. This lets Angular know that this module,
|
You might have noticed that the CLI adds `RouterModule.forRoot(routes)` to the `app-routing.module.ts` `imports` array.
|
||||||
`AppRoutingModule`, is a routing module and `forRoot()` specifies that this is the root
|
This lets Angular know that this module, `AppRoutingModule`, is a routing module and `forRoot()` specifies that this is the root routing module.
|
||||||
routing module. It configures all the
|
It configures all the routes you pass to it, gives you access to the router directives, and registers the `RouterService`.
|
||||||
routes you pass to it, gives you access to the router directives, and registers the `RouterService`.
|
|
||||||
Use `forRoot()` in the `AppRoutingModule`—that is, one time in the app at the root level.
|
Use `forRoot()` in the `AppRoutingModule`—that is, one time in the app at the root level.
|
||||||
|
|
||||||
The CLI also adds `RouterModule.forChild(routes)` to feature routing modules. This way, Angular
|
The CLI also adds `RouterModule.forChild(routes)` to feature routing modules.
|
||||||
knows that the route list is only responsible for providing additional routes and is intended for feature modules. You can use `forChild()` in multiple modules.
|
This way, Angular knows that the route list is only responsible for providing additional routes and is intended for feature modules.
|
||||||
|
You can use `forChild()` in multiple modules.
|
||||||
`forRoot()` contains injector configuration which is global; such as configuring the Router. `forChild()` has no injector configuration, only directives such as `RouterOutlet` and `RouterLink`.
|
|
||||||
|
|
||||||
|
The `forRoot()` method takes care of the *global* injector configuration for the Router.
|
||||||
|
The `forChild()` method has no injector configuration. It uses directives such as `RouterOutlet` and `RouterLink`.
|
||||||
For more information, see the [`forRoot()` pattern](guide/singleton-services#forRoot) section of the [Singleton Services](guide/singleton-services) guide.
|
For more information, see the [`forRoot()` pattern](guide/singleton-services#forRoot) section of the [Singleton Services](guide/singleton-services) guide.
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -209,4 +184,3 @@ You may also be interested in the following:
|
||||||
* [Types of Feature Modules](guide/module-types).
|
* [Types of Feature Modules](guide/module-types).
|
||||||
* [Route-level code-splitting in Angular](https://web.dev/route-level-code-splitting-in-angular/)
|
* [Route-level code-splitting in Angular](https://web.dev/route-level-code-splitting-in-angular/)
|
||||||
* [Route preloading strategies in Angular](https://web.dev/route-preloading-in-angular/)
|
* [Route preloading strategies in Angular](https://web.dev/route-preloading-in-angular/)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue