Sie sind hier: Weblog

AOT in Angular 2 mit Lazy Loading kombinieren

Foto ,
30.10.2016 02:00:00

In seinem Blogbeitrag Angular 2 AoT Compilation with webpack beschrieb Suguru Inatomi diese Woche, wie man mit webpack mit Angular 2 eine AOT-Kompilierung durchführen kann. Dazu nutzte er das Paket @ngtools/webpack, welches im Rahmen der CLI entwickelt wurde und ohne Änderungen am Source Code lediglich durch eine Anpassung der webpack-Konfig von JIT auf AOT umstellt.

Ich habe versucht, diese Idee auf mein Beispielprojekt anzuwenden und sie mit Lazy Loading zu verknüpfen. Dazu habe ich zusätzlich den angular2-router-loader für webpack ins Spiel gebracht. Ich denke, dass das später mal, wenn die CLI Lazy Loading in Kombination mit AOT unterstützt, nicht mehr notwendig ist.

Der vollständige Quellcode, der dabei entstanden ist, findet sich hier.

Unterm Strich habe ich für den Build die folgenden Pakete als devDependencies installiert:

"devDependencies": {
    "webpack": "^2.1.0-beta.25",
    "@angular/compiler-cli": "^2.1.1",
    "@ngtools/webpack": "^1.1.2",
    "angular2-router-loader": "^0.3.3",
    "angular2-template-loader": "^0.5.0",
    [...]
}

Zusätzlich habe ich die Loader @ngtools/webpack sowie angular2-router-loader für .ts-Dateien in der Datei webpack.config.js konfiguriert:

module: {
    rules: [
        [...]
        { test: /\.ts$/, loaders: [@ngtools/webpack, angular2-router-loader?aot=true&genDir=aot/app]}
    ],
},

Wichtig ist dabei, dass der angular2-router-loader die Parameter aot und genDir übergeben bekommt. Ersterer bereitet ihn für AOT vor und letzterer gibt an, wo der AOT-Compiler die generierten Dateien ablegt.

Zusätzlich ist noch das AOT-Plugin zu konfigurieren:

plugins: [
    new AotPlugin({
        tsConfigPath: ./tsconfig.json,
        entryModule: app/app.module#AppModule
    }),
    new webpack.optimize.UglifyJsPlugin({
        compress: {
            warnings: false
        },
        output: {
            comments: false
        },
        sourceMap: false
    }),
    [...]
}

Das tolle an dieser Lösung ist, dass der Rest der Anwendung für AOT nicht angepasst werden muss. Somit kann man zwei webpack-Konfigurationen verwenden: Eine AOT-Konfiguration für die Produktion und eine JIT-Konfiguration für die Entwicklung. Gerade da derzeit noch der AOT-Build mehr Zeit in Anspruch nimmt, empfiehlt sich diese Konfiguration. Hierbei sei jedoch gesagt, dass das Angular-Team an der Möglichkeit eines inkrementellen AOT-Builds arbeitet, sodass sich auch dieser in Zukunft sehr schnell gestalten sollte.

Für Lazy Loading ist nun nur noch in der Routen-Konfiguration mit loadChildren auf das nachzuladende Modul zu verweisen. Das angular2-router-loader schreibt diesen Code beim Build um, sodass er bei Bedarf die vom AOT-Compiler generierte Factory lädt.

export const ROUTE_CONFIG: Routes = [
    [...]
    {
        path: flug-buchen,
        loadChildren: ./flug/flug.module#FlugModule
    },
    [...]
];

Das gesamte Beispiel findet sich hier.