GEDOPLAN
Webprogrammierung

Angular 2 – Lazy Load Modules

Webprogrammierung

Unsere bisherigen Beispiele sind alle davon ausgegangen das es ein zentrales Modul gibt dessen Referenzen von Webpack analysiert und in in großes JavaScript-Bundle zusammen gefasst wird. Für kleine Anwendungen mag dieses Vorgehen gut funktionieren, wird die Anwendung jedoch komplexer und lassen sich einzelne Bereiche gut voneinander abtrennen bietet es sich an die eigenen Anwendung in mehrere Module zu unterteilen und diese nur bei Bedarf zu laden.

Webpack – prepare

Wir werden, anders als bisher, nicht mehr alle Komponenten die wir per Routing ansteuern wollen in unseren Routen importieren. Damit Webpack die Deklaration von Angular 2 spezifischen asynchronen Routen erkennt benötigen wir einen zusätzlichen Loader:

npm install angular2-router-loader --save-dev

Zusätzlich registrieren wir diesen Loader für unsereTypeScript-Dateien in unserer Konfiguration:

webpack.common.js

...
{
    test: /\.ts$/,
    loaders: ['ts-loader','angular2-router-loader']
}
...

Modul die Zweite

In unserem sehr einfachen Beispiel wollen wir nun die „zweite“ Seite unserer Anwendung in ein eigenes Modul verschieben, um diese später nur bei Bedarf laden zu können. Dazu erzeugen wir eine neue Modul-Defitionsdatei mit einer Route-Definition für unser Unter-Modul:

hello.module.ts

import { NgModule}      from '@angular/core';
import { routing } from './hello.routing';
import {HelloComponent} from '../'

@NgModule({
    imports: [routing],
    declarations: [HelloComponent],
    providers: [ ],
    exports: [HelloComponent]
})
export class HelloModule { }

hello.routing.ts

import { Routes, RouterModule } from '@angular/router';
import {HelloComponent} from '../'

const appRoutes: Routes = [
    { path: '', component: HelloComponent}
];

export const routing = RouterModule.forChild(appRoutes);

In großen Teilen unterscheidet sich diese Modul-Definition nicht von unserem Root-Modul. Wir geben hier lediglich kein „bootstrap“-Attribut an. Darüber hinaus referenzieren wir natürlich nur die externen Module („imports“), die eigenen Komponenten („declarations“) und Provider („providers“) die in diesem Modul gültig sind. Auch die Routing-Datei ändert sich lediglich an einer Stelle. Anstatt das Routing als Root-Navigation zu exportieren (.forRoot) geben wir lediglich an das es sich bei diesen exportierten Routen um Navigationen für ein Kind-Modul handelt (.forChild).

Laden? Später bitte

Die entscheiden Anpassung in unserem Root-Modul geschieht nun in Routen-Definition:

app.routing.ts

// -- ALT --
...
const appRoutes: Routes = [
    { path: '', component: HomeComponent},
    { path: 'hello', component: HelloComponent},
    { path: 'animation', component: AnimationComponent},
];
...

// -- NEU --

import { Routes, RouterModule } from '@angular/router';
import {HomeComponent} from './components'

const appRoutes: Routes = [
    { path: '', component: HomeComponent},
     { path: 'hello', loadChildren: './components/+hello/hello.module#HelloModule' },
     { path: 'animation', loadChildren: './components/+animation/animation.module#AnimationModule' }
];

export const appRoutingProviders: any[] = [

];

export const routing = RouterModule.forRoot(appRoutes);

Anstatt direkt die Kind-Komponenten zu referenzieren verwenden wir eine spezielle URL-Syntax die dank des oben installierten und registrierten Webpack-Loaders auch beim Bundling der Anwendung funktioniert. Asynchrone Routen werden wie hier zu sehen mittels „loadChildren“ Attribut deklariert, gefolgt von einem String im Aufbau:

„[Pfad-zur-Modul-Datei]#[ModulName]“

(die hier verwendeten Bezeichnungen der Ordner mit vorangestelltem „+“ Zeichen ist nicht verpflichtend, ist aber eine allgemeine akzeptierte Konvention um asynchrone Komponenten zu markieren)

Alles zu seiner Zeit

Die oben gezeigte Konfiguration führt nun dazu das Webpack mehrere Bundles ausprägt, ein Bundle pro Module, sodass diese später geladen werden können. Dies lässt sich dann auch in der laufenden Anwendung nachvollziehen. Bei der Navigation zwischen den Seiten (/ Modulen) lädt Angular diese Kind-Komponenten erst wenn sie angesteuert werden:

angular2_lazy_routing_network

Lazy-Loaded Routes ist eine optimale und einfach zu verwendete Möglichkeit die Anwendung in schneller ladbare Teile zu teilen und den Anwender bei großen Anwendungen nicht mit Programmteilen zu belasten die er vielleicht gar nicht verwendet. Das gezeigteBeispiel gibt es wie immer auch bei Github:

https://github.com/dominikmathmann/angular-webpack-starter/tree/lazy-loaded-routes

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Bitte füllen Sie dieses Feld aus.
Bitte füllen Sie dieses Feld aus.
Bitte gib eine gültige E-Mail-Adresse ein.
Sie müssen den Bedingungen zustimmen, um fortzufahren.

Autor

Diesen Artikel teilen

LinkedIn
Xing

Gibt es noch Fragen?

Fragen beantworten wir sehr gerne! Schreibe uns einfach per Kontaktformular.

Kurse

weitere Blogbeiträge

IT-Training - GEDOPLAN
Jakarta EE (Java EE)

JPA mit dynamischer DB-Verbindung

In Java-EE-Anwendungen, die JPA zum DB-Zugriff nutzen, wird im Normalfall eine Datasource zur Spezifikation der Datenbankverbindung genutzt: <persistence ...> <persistence-unit…

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!