Ich möchte in diesem Thread die neueste beste (und hoffentlich die einfachste) Methode zum Bündeln von Angular (Version 2, 4, ...) für die Produktion auf einem Live-Webserver verfolgen und aktualisieren.
Fügen Sie bitte die Angular-Version in die Antworten ein, damit wir besser verfolgen können, wenn sie zu späteren Releases wechselt.
2.x, 4.x, 5.x, 6.x, 7.x
(TypeScript) mit Angular CLInpm install -g @angular/cli
ng new projectFolder
erstellt eine neue Anwendungng build --prod
(in der Befehlszeile ausführen, wenn das Verzeichnis projectFolder
ist)
Flag prod
-Bundle für die Produktion (siehe Angular-Dokumentation für die Liste der Optionen, die im Produktions-Flag enthalten sind).
Komprimieren Sie mit Brotli-Komprimierung die Ressourcen mit dem folgenden Befehl
for i in dist/*; do brotli $i; done
Bundles werden standardmäßig in projectFolder/dist (/ $ projectFolder for 6) generiert}
Größen mit Angular 7.2.5
mit CLI 7.3.1
und Option CSS ohne Angular-Routing
dist/main.[hash].bundle.js
Ihre Anwendung wurde gebündelt [Größe: 151 KB für neue Angular CLI-Anwendung leer, 37 KB komprimiert].dist/polyfill.[hash].bundle.js
die Polyfill-Abhängigkeiten (@angular, RxJS ...) gebündelt [Größe: 41 KB für neue Angular-CLI-Anwendung leer, 12 KB komprimiert].dist/index.html
Einstiegspunkt Ihrer Bewerbung.dist/inline.[hash].bundle.js
webpack loaderdist/style.[hash].bundle.css
die Stildefinitionendist/assets
-Ressourcen, die aus der Konfiguration der Angular-CLI-Assets kopiert wurdenSie können eine Vorschau Ihrer Anwendung erhalten, indem Sie den Befehl ng serve --prod
verwenden, der einen lokalen HTTP-Server startet, sodass auf die Anwendung mit Produktionsdateien mit http: // localhost: 4200 zugegriffen werden kann.
Für eine Produktionsverwendung müssen Sie alle Dateien aus dem Ordner dist
auf dem HTTP-Server Ihrer Wahl bereitstellen.
2.0.1 Final
mit Gulp (TypeScript - Target: ES5)npm install
(wird in cmd ausgeführt, wenn das Verzeichnis projektordner ist)npm run bundle
(wird in cmd ausgeführt, wenn das Verzeichnis projektordner ist)
Bundles werden in projectFolder/bundles/generiert
bundles/dependencies.bundle.js
[size: ~ 1 MB (so klein wie möglich)] bundles/app.bundle.js
[size: hängt von Ihrem Projekt ab, mein ist ~ 0.5 MB] var gulp = require('gulp'),
tsc = require('gulp-TypeScript'),
Builder = require('systemjs-builder'),
inlineNg2Template = require('gulp-inline-ng2-template');
gulp.task('bundle', ['bundle-app', 'bundle-dependencies'], function(){});
gulp.task('inline-templates', function () {
return gulp.src('app/**/*.ts')
.pipe(inlineNg2Template({ useRelativePaths: true, indent: 0, removeLineBreaks: true}))
.pipe(tsc({
"target": "ES5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": true,
"noImplicitAny": false
}))
.pipe(gulp.dest('dist/app'));
});
gulp.task('bundle-app', ['inline-templates'], function() {
// optional constructor options
// sets the baseURL and loads the configuration file
var builder = new Builder('', 'dist-systemjs.config.js');
return builder
.bundle('dist/app/**/* - [@angular/**/*.js] - [rxjs/**/*.js]', 'bundles/app.bundle.js', { minify: true})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
gulp.task('bundle-dependencies', ['inline-templates'], function() {
// optional constructor options
// sets the baseURL and loads the configuration file
var builder = new Builder('', 'dist-systemjs.config.js');
return builder
.bundle('dist/app/**/*.js - [dist/app/**/*.js]', 'bundles/dependencies.bundle.js', { minify: true})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
{
"name": "angular2-quickstart",
"version": "1.0.0",
"scripts": {
***
"gulp": "gulp",
"rimraf": "rimraf",
"bundle": "gulp bundle",
"postbundle": "rimraf dist"
},
"license": "ISC",
"dependencies": {
***
},
"devDependencies": {
"rimraf": "^2.5.2",
"gulp": "^3.9.1",
"gulp-TypeScript": "2.13.6",
"gulp-inline-ng2-template": "2.0.1",
"systemjs-builder": "^0.15.16"
}
}
(function(global) {
// map tells the System loader where to look for things
var map = {
'app': 'app',
'rxjs': 'node_modules/rxjs',
'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
'@angular': 'node_modules/@angular'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'app/boot.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { defaultExtension: 'js' }
};
var packageNames = [
'@angular/common',
'@angular/compiler',
'@angular/core',
'@angular/forms',
'@angular/http',
'@angular/platform-browser',
'@angular/platform-browser-dynamic',
'@angular/router',
'@angular/router-deprecated',
'@angular/testing',
'@angular/upgrade',
];
// add package entries for angular packages in the form '@angular/common': { main: 'index.js', defaultExtension: 'js' }
packageNames.forEach(function(pkgName) {
packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});
var config = {
map: map,
packages: packages
};
// filterSystemConfig - index.asp's chance to modify config before we register it.
if (global.filterSystemConfig) { global.filterSystemConfig(config); }
System.config(config);
})(this);
var map = {
'app': 'dist/app',
};
dist-systemjs.config.js
nach den Bundle-Tags setzen, kann das Programm zwar ausgeführt werden, das Abhängigkeitsbündel wird jedoch ignoriert, und Abhängigkeiten werden angezeigt aus dem Ordner node_modules
geladen werden.<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<base href="/"/>
<title>Angular</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>
<my-app>
loading...
</my-app>
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.min.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.js"></script>
<script src="dist-systemjs.config.js"></script>
<!-- Project Bundles. Note that these have to be loaded AFTER the systemjs.config script -->
<script src="bundles/dependencies.bundle.js"></script>
<script src="bundles/app.bundle.js"></script>
<script>
System.import('app/boot').catch(function (err) {
console.error(err);
});
</script>
</body>
</html>
Das Beste was ich noch tun konnte :)
Das Angular2-Team hat ein Tutorial für die Verwendung von Webpack veröffentlicht
Ich habe die Dateien aus dem Tutorial erstellt und in einem kleinen GitHub-Seed-Projekt abgelegt. So können Sie den Workflow schnell ausprobieren.
Anweisungen:
npm install
npm start. Zur Entwicklung. Dadurch wird ein virtueller "dist" -Ordner erstellt, der an Ihrer localhost-Adresse geladen wird.
npm Build ausführen. Für die Produktion. "Dadurch wird eine physische" dist "-Ordner-Version erstellt, die an einen Webserver gesendet werden kann. Der dist-Ordner ist 7,8 MB, aber zum Laden der Seite in einem Webbrowser sind nur 234 KB erforderlich.
Dieses Webpack Starter Kit bietet einige Testfunktionen als das obige Tutorial und scheint recht beliebt zu sein.
Angular.io hat ein Schnellstart-Tutorial. Ich habe dieses Tutorial kopiert und um einige einfache Schluckaufgaben erweitert, um alles in einem dist-Ordner zu bündeln, der auf den Server kopiert werden kann und genau so funktioniert. Ich habe versucht alles zu optimieren, um mit Jenkis CI gut zu funktionieren, so dass node_modules zwischengespeichert werden können und nicht kopiert werden müssen.
Quellcode mit Beispiel-App auf Github: https://github.com/Anjmao/angular2-production-workflow
Node: Sie können zwar immer Ihren eigenen Build-Prozess erstellen, aber ich empfehle dringend die Verwendung von angle-cli, da alle erforderlichen Arbeitsabläufe vorhanden sind und jetzt perfekt funktioniert. Wir verwenden es bereits in der Produktion und haben überhaupt keine Probleme mit angle-cli.
Dies unterstützt:
ng neuer Projektname --routing
Sie können --style=scss
für die Unterstützung von SASS .scss hinzufügen.
Sie können --ng4
für die Verwendung von Winkel 4 anstelle von Winkel 2 hinzufügen.
Nach dem Erstellen des Projekts führt die CLI automatisch npm install
für Sie aus. Wenn Sie stattdessen Yarn verwenden möchten oder einfach nur das Projekt-Skelett ohne Installation betrachten möchten, geben Sie prüfen Sie hier, wie das geht .
Im Projektordner:
ng Build -Prod
In der aktuellen Version müssen Sie --aot
manuell angeben, da es im Entwicklungsmodus verwendet werden kann (obwohl dies aus Gründen der Langsamkeit nicht praktikabel ist).
Dies führt auch eine AoT-Kompilierung für noch kleinere Bundles durch (kein Angular-Compiler, sondern generierte Compiler-Ausgabe). Die Bundles sind mit AoT viel kleiner, wenn Sie Angular 4 verwenden, da der generierte Code kleiner ist.
Sie können Ihre App mit AoT im Entwicklungsmodus (Quellcaps, keine Minifizierung) und AoT testen, indem Sie ng build --aot
ausführen.
Das Standardausgabeverzeichnis ist ./dist
, obwohl es in ./angular-cli.json
geändert werden kann.
Das Ergebnis des Erstellungsschritts ist folgendes:
(Hinweis: <content-hash>
bezieht sich auf den Hash-/Fingerabdruck des Inhalts der Datei, die als Cache-Busting-Methode gedacht ist. Dies ist möglich, da Webpack die script
-Tags selbst schreibt.)
./dist/assets
./src/assets/**
kopiert wurden./dist/index.html
./src/index.html
aus, nachdem Webpack-Skripts hinzugefügt wurden./angular-cli.json
konfigurierbar../dist/inline.js
./dist/main.<content-hash>.bundle.js
./dist/styles.<content-hash>.bundle.js
In älteren Versionen wurden auch gezippte Versionen erstellt, um deren Größe und .map
sourcemaps-Dateien zu überprüfen. Dies geschieht jedoch nicht mehr, da die Benutzer immer wieder nach dem Entfernen dieser Dateien gefragt haben.
In bestimmten anderen Fällen finden Sie möglicherweise andere unerwünschte Dateien/Ordner:
./out-tsc/
./src/tsconfig.json
s outDir
./out-tsc-e2e/
./e2e/tsconfig.json
s outDir
./dist/ngfactory/
Bis heute finde ich das Ahead-of-Time-Compilation-Kochbuch als das beste Rezept für das Produktionsbündeln. Sie finden es hier: https://angular.io/docs/ts/latest/cookbook/aot-compiler.html
Meine bisherige Erfahrung mit Angular 2 besteht darin, dass AoT die kleinsten Builds mit fast keiner Ladezeit erstellt. Und das Wichtigste, denn es geht hier um die Frage: Sie müssen nur wenige Dateien zur Produktion schicken.
Dies scheint darauf zurückzuführen zu sein, dass der Angular-Compiler nicht mit den Produktions-Builds ausgeliefert wird, da die Vorlagen "Ahead of Time" kompiliert werden. Es ist auch sehr cool zu sehen, wie Ihr HTML-Template-Markup in Javascript-Anweisungen umgewandelt wurde, die sich nur schwer in den ursprünglichen HTML-Code zurückentwickeln lassen.
Ich habe ein einfaches Video erstellt, in dem ich Downloadgröße, Anzahl der Dateien usw. für eine Angular 2-App in dev vs AoT build demonstriere. Das können Sie hier sehen:
Den im Video verwendeten Quellcode finden Sie hier:
**Production build with
- Angular Rc5
- Gulp
- typescripts
- systemjs**
1)con-cat all js files and css files include on index.html using "gulp-concat".
- styles.css (all css concat in this files)
- shims.js(all js concat in this files)
2)copy all images and fonts as well as html files with gulp task to "/dist".
3)Bundling -minify angular libraries and app components mentioned in systemjs.config.js file.
Using gulp 'systemjs-builder'
SystemBuilder = require('systemjs-builder'),
gulp.task('system-build', ['tsc'], function () {
var builder = new SystemBuilder();
return builder.loadConfig('systemjs.config.js')
.then(function () {
builder.buildStatic('assets', 'dist/app/app_libs_bundle.js')
})
.then(function () {
del('temp')
})
});
4)Minify bundles using 'gulp-uglify'
jsMinify = require('gulp-uglify'),
gulp.task('minify', function () {
var options = {
mangle: false
};
var js = gulp.src('dist/app/shims.js')
.pipe(jsMinify())
.pipe(gulp.dest('dist/app/'));
var js1 = gulp.src('dist/app/app_libs_bundle.js')
.pipe(jsMinify(options))
.pipe(gulp.dest('dist/app/'));
var css = gulp.src('dist/css/styles.min.css');
return merge(js,js1, css);
});
5) In index.html for production
<html>
<head>
<title>Hello</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8" />
<link rel="stylesheet" href="app/css/styles.min.css" />
<script type="text/javascript" src="app/shims.js"></script>
<base href="/">
</head>
<body>
<my-app>Loading...</my-app>
<script type="text/javascript" src="app/app_libs_bundle.js"></script>
</body>
</html>
6) Now just copy your dist folder to '/www' in wamp server node need to copy node_modules in www.
Sie können Ihre Winkelanwendung mit github
mit angle-cli-ghpages bereitstellen.
schauen Sie sich den Link an, um zu erfahren, wie Sie dieses Cli implementieren können.
die bereitgestellte Website wird normalerweise in einem Zweig in github
gespeichert
gh-pages
use kann den git-Zweig klonen und wie eine statische Website auf Ihrem Server verwenden
"Best" hängt vom Szenario ab. Es gibt Zeiten, in denen Sie nur auf das kleinstmögliche Einzelpaket achten, aber in großen Apps müssen Sie möglicherweise das langsame Laden in Betracht ziehen. An einem bestimmten Punkt wird es unpraktisch, die gesamte App als einzelnes Bundle bereitzustellen.
In letzterem Fall ist Webpack im Allgemeinen die beste Methode, da es die Codeaufteilung unterstützt.
Für ein einzelnes Bundle würde ich Rollup oder den Closure-Compiler in Betracht ziehen, wenn Sie sich mutig fühlen :-)
Ich habe Beispiele aller Angular-Bundler erstellt, die ich hier jemals verwendet habe: http://www.syntaxsuccess.com/viewarticle/angular-production-builds
Der Code ist hier zu finden: https://github.com/thelgevold/angular-2-samples
Winkelversion: 4.1.x
Richten Sie das Winkel-4-Paket innerhalb einer Minute mit Webpack 3 ein, und Ihr ENV-Paket für Entwicklung und Produktion ist ohne Probleme verfügbar
Bitte versuchen Sie es unter CLI-Befehl im aktuellen Projektverzeichnis. Es wird ein dist-Ordnerpaket erstellt. Sie können also alle Dateien im Ordner dist für Bereitstellungen hochladen.
ng build --prod --aot --base-href.