Qual è il metodo migliore per raggruppare Angular (versione 2, 4, 6, ...) per la produzione su un web server live.
Includi la versione angolare tra le risposte in modo da poter tracciare meglio quando passa alle versioni successive.
Qual è il metodo migliore per raggruppare Angular (versione 2, 4, 6, ...) per la produzione su un web server live.
Includi la versione angolare tra le risposte in modo da poter tracciare meglio quando passa alle versioni successive.
Risposte:
2.x, 4.x, 5.x, 6.x, 7.x, 8.x, 9.x
(TypeScript) con CLI angolarenpm install -g @angular/cli
ng new projectFolder
crea una nuova applicazioneng build --prod
(eseguito nella riga di comando quando la directory è projectFolder
)
prod
bundle di flag per la produzione (consultare la documentazione angolare per l'elenco delle opzioni incluse con il flag di produzione).
Comprimi usando la compressione Brotli le risorse usando il seguente comando
for i in dist/*; do brotli $i; done
i bundle vengono generati per impostazione predefinita in projectFolder / dist (/ $ projectFolder per 6)
Dimensioni con Angular 9.0.0
con CLI 9.0.1
e opzione CSS senza routing angolare
dist/main-[es-version].[hash].js
Applicazione in bundle [dimensione ES5: 158 KB per la nuova applicazione della CLI angolare vuota, 40 KB compressi].dist/polyfill-[es-version].[hash].bundle.js
le dipendenze polyfill (@angular, RxJS ...) raggruppate [dimensione ES5: 127 KB per la nuova applicazione della CLI angolare vuota, 37 KB compressi].dist/index.html
punto di ingresso della domanda.dist/runtime-[es-version].[hash].bundle.js
caricatore webpackdist/style.[hash].bundle.css
le definizioni di stiledist/assets
risorse copiate dalla configurazione degli asset della CLI angolareÈ possibile ottenere un'anteprima dell'applicazione utilizzando il ng serve --prod
comando che avvia un server HTTP locale in modo tale che l'applicazione con file di produzione sia accessibile tramite http: // localhost: 4200 .
Per un utilizzo in produzione, è necessario distribuire tutti i file dalla dist
cartella nel server HTTP di propria scelta.
2.0.1 Final
utilizzando Gulp (TypeScript - Target: ES5)npm install
(eseguito in cmd quando direcory è projectFolder)npm run bundle
(eseguito in cmd quando direcory è projectFolder)
i bundle vengono generati in projectFolder / bundles /
bundles/dependencies.bundle.js
[ dimensione: ~ 1 MB (il più piccolo possibile)]
bundles/app.bundle.js
[ dimensione: dipende dal tuo progetto , il mio è ~ 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
tag dopo i tag bundle consentirebbe comunque l'esecuzione del programma ma il bundle di dipendenze verrebbe ignorato e le dipendenze verrebbero caricate dalla node_modules
cartella.<!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>
Il meglio che potrei fare ancora :)
inline-templates
viene eseguito, allinea i modelli, quindi crea una copia di tutte le cartelle e i file delle app in dist/app
. Poi, nel dist-systemjs.config.js
mappare app
a dist/app
che è una cartella che non esisterà se si utilizza la dist
cartella come root. Non vorresti eseguire la tua app dalla dist
cartella? E se è così, non avresti una dist
cartella nidificata nella dist
cartella principale . Mi manca qualcos'altro qui. Non hai bisogno di dire a systemjs di usare i tuoi file raggruppati e non i soliti file trovati nella dist/app
cartella?
Il team di Angular2 ha pubblicato un tutorial per l'utilizzo di Webpack
Ho creato e inserito i file dal tutorial in un piccolo progetto seed GitHub . Quindi puoi provare rapidamente il flusso di lavoro.
Istruzioni :
npm install
inizio npm . Per lo sviluppo. Questo creerà una cartella "dist" virtuale che verrà caricata sul tuo indirizzo localhost.
npm run build . Per la produzione. "Ciò creerà una versione fisica della cartella" dist "che può essere inviata a un server Web. La cartella dist è 7,8 MB, ma per caricare la pagina in un browser Web sono necessari solo 234 KB.
Questo Starter Kit Webpack offre alcune funzionalità di test in più rispetto all'esercitazione di cui sopra e sembra piuttosto popolare.
Angular.io ha tutorial di avvio rapido. Ho copiato questo tutorial ed esteso con alcune semplici attività gulp per raggruppare tutto in una cartella dist che può essere copiata sul server e funzionare in questo modo. Ho cercato di ottimizzare tutto per funzionare bene su Jenkis CI, quindi node_modules può essere memorizzato nella cache e non è necessario copiarlo.
Codice sorgente con app di esempio su Github: https://github.com/Anjmao/angular2-production-workflow
Passi per la produzioneNodo : Mentre puoi sempre creare il tuo processo di compilazione, ma consiglio vivamente di usare angular-cli, perché ha tutti i flussi di lavoro necessari e funziona perfettamente ora. Lo stiamo già utilizzando in produzione e non abbiamo alcun problema con angular-cli.
Questo supporta:
di nuovo project-name --routing
È possibile aggiungere --style=scss
per il supporto SASS .scss.
È possibile aggiungere --ng4
per l'utilizzo di Angular 4 anziché Angular 2.
Dopo aver creato il progetto, l'interfaccia della riga di comando verrà eseguita automaticamente npm install
per te. Se invece vuoi usare Yarn o vuoi semplicemente guardare lo scheletro del progetto senza installarlo, controlla come farlo qui .
All'interno della cartella del progetto:
di build -prod
Nella versione corrente è necessario specificare --aot
manualmente, poiché può essere utilizzato in modalità di sviluppo (anche se non è pratico a causa della lentezza).
Questo esegue anche la compilazione AoT per bundle ancora più piccoli (nessun compilatore angolare, invece, ha generato l'output del compilatore). I bundle sono molto più piccoli con AoT se si utilizza Angular 4 poiché il codice generato è più piccolo.
Puoi testare la tua app con AoT in modalità di sviluppo (mappe di origine, nessuna minificazione) e AoT eseguendo ng build --aot
.
La directory di destinazione predefinita è ./dist
, sebbene possa essere cambiata in ./angular-cli.json
.
Il risultato del passaggio di creazione è il seguente:
(Nota: si <content-hash>
riferisce all'hash / impronta digitale del contenuto del file che si intende essere un modo di busting della cache, questo è possibile poiché Webpack scrive i script
tag da solo)
./dist/assets
./src/assets/**
./dist/index.html
./src/index.html
, dopo aver aggiunto gli script webpack ad esso, ./angular-cli.json
./dist/inline.js
./dist/main.<content-hash>.bundle.js
./dist/styles.<content-hash>.bundle.js
Nelle versioni precedenti ha anche creato versioni gzip per verificarne le dimensioni e .map
file sourcemap, ma ciò non accade più poiché le persone continuavano a chiedere di rimuoverle.
In alcune altre occasioni, potresti trovare altri file / cartelle indesiderati:
./out-tsc/
./src/tsconfig.json
'soutDir
./out-tsc-e2e/
./e2e/tsconfig.json
'soutDir
./dist/ngfactory/
<content-hash>
dai bundle in prod. può causare problemi nell'ottenere l'ultimo pacchetto?
Ad oggi trovo ancora il ricettario sulla compilazione anticipata come la migliore ricetta per il raggruppamento di produzione. Puoi trovarlo qui: https://angular.io/docs/ts/latest/cookbook/aot-compiler.html
La mia esperienza con Angular 2 finora è che AoT crea le build più piccole senza quasi nessun tempo di caricamento. E, soprattutto, la domanda qui è: devi solo spedire alcuni file alla produzione.
Ciò sembra essere dovuto al fatto che il compilatore angolare non verrà distribuito con le build di produzione poiché i modelli vengono compilati "Ahead of Time". È anche molto bello vedere il markup del tuo modello HTML trasformato in istruzioni javascript che sarebbe molto difficile decodificare nell'HTML originale.
Ho realizzato un semplice video in cui dimostro le dimensioni del download, il numero di file, ecc. Per un'app Angular 2 in sviluppo dev vs AoT - che puoi vedere qui:
Troverai il codice sorgente utilizzato nel video qui:
**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="https://stackoverflow.com/">
</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.
Puoi distribuire la tua applicazione angolaregithub
usando
angular-cli-ghpages
controlla il link per scoprire come distribuire usando questo cli.
il sito Web distribuito verrà archiviato in qualche filiale in github
genere
GH-pagine
use può clonare il ramo git e usarlo come sito Web statico nel tuo server
"Migliore" dipende dallo scenario. Ci sono momenti in cui ti preoccupi solo del singolo bundle più piccolo possibile, ma nelle app di grandi dimensioni potresti dover considerare il caricamento lento. A un certo punto diventa poco pratico servire l'intera app come un unico pacchetto.
In quest'ultimo caso Webpack è generalmente il modo migliore poiché supporta la suddivisione del codice.
Per un singolo bundle prenderei in considerazione Rollup o il compilatore Closure se ti senti coraggioso :-)
Ho creato esempi di tutti i bundler angolari che abbia mai usato qui: http://www.syntaxsuccess.com/viewarticle/angular-production-builds
Il codice è disponibile qui: https://github.com/thelgevold/angular-2-samples
Versione angolare: 4.1.x
Basta configurare angular 4 con webpack 3 in un minuto e il pacchetto ENV di sviluppo e produzione sarà pronto senza alcun problema, basta seguire il documento github di seguito
Prova sotto il comando CLI nella directory del progetto corrente. Creerà un pacchetto di cartelle dist. in modo da poter caricare tutti i file nella cartella dist per le distribuzioni.
di build --prod --aot --base-href.
ng serve a servire la nostra applicazione per scopi di sviluppo. E per la produzione? Se esaminiamo il nostro file package.json, possiamo vedere che ci sono script che possiamo usare:
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
Lo script build utilizza la build ng della CLI angolare con il flag --prod. Proviamo ora. Possiamo farlo in due modi:
# usando gli script npm
npm run build
# usando direttamente il cli
ng build --prod
Questa volta ci vengono dati quattro file anziché i cinque. Il flag --prod dice ad Angular di ridurre le dimensioni della nostra applicazione.