65.9K
CodeProject 正在变化。 阅读更多。
Home

在 ASP.NET Core AngularSPA 中延迟加载 NgModules

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2017 年 7 月 20 日

CPOL

2分钟阅读

viewsIcon

10768

本文档展示了如何配置 ASP.NET Core AngularSPA 启动项目以提供一个延迟加载的 Angular 模块。

Angular 具有延迟加载模块的强大功能。配置为延迟加载的模块可以显著节省应用程序启动时间。延迟加载模块的设置是在应用程序的路由配置部分完成的。

如标题所示,我们将使用 Visual Studio 2017 Preview (2) 随附的 AngularSPA 模板进行演示。

配置为延迟加载模块的路由会向服务器发送 HTTP GET 请求,服务器反过来会返回一个代码块中的模块。这仅在应用程序生命周期中首次激活路由器时发生。

以下是 AngularSPA 启动项目中 AppModuleShared (app.module.shared.ts) 的设置方式

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router'; 
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './components/app/app.component';
import { NavMenuComponent } from './components/navmenu/navmenu.component';
import { HomeComponent } from './components/home/home.component';
import { FetchDataComponent } from './components/fetchdata/fetchdata.component';
import { CounterComponent } from './components/counter/counter.component';

@NgModule({
    declarations: [
        AppComponent,
        NavMenuComponent,
        CounterComponent,
        FetchDataComponent,
        HomeComponent
    ],
    imports: [
        CommonModule,
        HttpModule,
        FormsModule,
        ReactiveFormsModule,
        RouterModule.forRoot([
            { path: '', redirectTo: 'home', pathMatch: 'full' },
            { path: 'home', component: HomeComponent },
            { path: 'counter', component: CounterComponent },
            { path: 'fetch-data', component: FetchDataComponent },
            { path: '**', redirectTo: 'home' }
        ])
    ]
})
export class AppModuleShared {
}

假设 CounterComponent 是访问频率较低的组件之一。将它放在一个单独的模块下并按需加载,将更有利于性能。

counter 文件夹下添加一个 counter.module.ts 文件,并添加以下模块代码

import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CounterComponent } from './counter.component';

@NgModule({
    imports: [
        RouterModule.forChild([{ path: '', component: CounterComponent }])
    ],
    exports: [RouterModule],
    declarations: [CounterComponent]
})

export class CounterModule { }

请注意,该模块具有自己的路由配置。由于 CounterModule 是一个特性模块,因此在路由配置中使用 forChild 方法而不是 forRoot

修改 app.module.shared.ts 并从文件中删除 CounterComponet 的引用

  • 删除 import 语句
  • declarations 数组中删除组件声明。

以下是修改后的 app.module.shared.ts 代码

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router'; 
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './components/app/app.component';
import { NavMenuComponent } from './components/navmenu/navmenu.component';
import { HomeComponent } from './components/home/home.component';
import { FetchDataComponent } from './components/fetchdata/fetchdata.component';

@NgModule({
    declarations: [
        AppComponent,
        NavMenuComponent,
        FetchDataComponent,
        HomeComponent
    ],
    imports: [
        CommonModule,
        HttpModule,
        FormsModule,
        ReactiveFormsModule,
        RouterModule.forRoot([
            { path: '', redirectTo: 'home', pathMatch: 'full' },
            { path: 'home', component: HomeComponent },
            { path: 'counter', loadChildren: 
            './components/counter/counter.module#CounterModule' },
            { path: 'fetch-data', component: FetchDataComponent },
            { path: '**', redirectTo: 'home' }
        ])
    ]
})
export class AppModuleShared {
}

现在,我们不再拥有 component 属性;而是用 loadChilden 替换了它。属性 loadChildren 采用指向将被延迟加载的模块的相对路径。请注意,模块名称本身已添加到路径字符串的末尾 (#CounterModule)。这是因为 CounterModule 类**不是**文件的 default 导出。

配置的最后一部分是在 webpack.configure.js 文件中。但首先,我们需要安装 angular2-router-loader 包。

angular2-router-loader 是一个用于 Angular 的 Webpack 加载器,它使用 Angular Router 启用基于 string 的模块加载。使用以下 npm install 命令安装该包

npm install  --save angular2-router-loader

当然,在运行命令之前,请将您的命令提示符的目录更改为您的应用程序根目录。

现在开始在 webpack.configure.js 中配置 angular2-router-loader 包。在 use 数组中,为 angular-router-loader 连同 awesome-typescript-loader?silent=true, angular2-template-loader 添加另一个条目。模块部分现在应该如下所示

module: {
    rules: [
        { test: /\.ts$/, include: /ClientApp/, 
                use: ['awesome-typescript-loader?silent=true', 
                'angular2-template-loader', 'angular2-router-loader'] },
        { test: /\.html$/, use: 'html-loader?minimize=false' },
        { test: /\.css$/, use: ['to-string-loader', 'css-loader'] },
        { test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
    ]
}

完成之后,构建并运行应用程序。为了确保 CounterComponent 来自一个延迟加载的模块,请打开浏览器的 developer 控制台并转到 network 选项卡。导航到 counter 路由(使用侧边菜单)现在将通过 HTTP GET 请求加载一个新的代码块。

演示的 Git 仓库 - https://github.com/fiyazbinhasan/AngularSPA

© . All rights reserved.