¿Cuál es el mejor método para empaquetar Angular (versión 2, 4, 6, ...) para la producción en un servidor web en vivo.
Por favor, incluya la versión de Angular en las respuestas para que podamos hacer un mejor seguimiento cuando se mueve a versiones posteriores.
2.x, 4.x, 5.x, 6.x, 7.x, 8.x
(TypeScript) con Angular CLInpm install -g @angular/cli
ng new projectFolder
crea una nueva aplicaciónng build --prod
(se ejecuta en línea de comandos cuando el directorio es carpeta de proyecto
)
marcar el bundle prod
para producción (ver la documentación de Angular para la lista de opciones incluidas con la bandera de producción).
Comprime usando Brotli compression los recursos usando el siguiente comando
for i in dist/*; do brotli $i; done
Los paquetes se generan por defecto en carpetaproyecto/dist(/$carpetaproyecto para 6).
Tamaño con Angular 8.2.11
con CLI 8.3.13
y opción CSS sin enrutamiento Angular
dist/main-[es-version].[hash].js
Tu aplicación empaquetada [ tamaño ES5: 188 KB para la nueva aplicación Angular CLI vacía, 44 KB comprimida].dist/polyfill-[es-version].[hash].bundle.js
las dependencias de polyfill (@angular, RxJS...) agrupadas [ tamaño ES5: 122 KB para la nueva aplicación Angular CLI vacía, 36 KB comprimidos].dist/index.html
de tu aplicación.dist/runtime-[es-version].[hash].bundle.js
cargador de webpackdist/style.[hash].bundle.css
las definiciones de estilodist/assets
los recursos copiados de la configuración de activos de Angular CLIPuedes obtener una vista previa de tu aplicación usando el comando ng serve --prod
que inicia un servidor HTTP local de forma que la aplicación con los archivos de producción es accesible usando http://localhost:4200.
Para un uso en producción, tienes que desplegar todos los archivos de la carpeta dist
en el servidor HTTP de tu elección.
idioma-todo: lang-ts -->
2.0.1 Final
usando Gulp (TypeScript - Target: ES5)npm install
(ejecutar en cmd cuando la dirección es projectFolder)npm run bundle
(se ejecuta en cmd cuando la dirección es projectFolder)Los bundles se generan en carpeta de proyecto / bundles /
bundles/dependencies.bundle.js
[ tamaño: ~ 1 MB (lo más pequeño posible) ]bundles/app.bundle.js
[ tamaño: depende de tu proyecto, el mío es ~ 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
después de las etiquetas del bundle permitiría que el programa se ejecutara pero el bundle de dependencias sería ignorado y las dependencias se cargarían desde la carpeta node_modules
.<!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>
Lo mejor que pude hacer todavía :)
Angular.io tiene un tutorial de inicio rápido. He copiado este tutorial y lo he ampliado con algunas tareas simples de gulp para empaquetar todo en la carpeta dist que se puede copiar en el servidor y trabajar así. Traté de optimizar todo para que funcione bien en Jenkis CI, por lo que los node_modules pueden ser cacheados y no necesitan ser copiados.
Código fuente con la aplicación de ejemplo en Github: https://github.com/Anjmao/angular2-production-workflow
Nodo: Aunque siempre puedes crear tu propio proceso de compilación, te recomiendo encarecidamente que utilices angular-cli, porque tiene todos los flujos de trabajo necesarios y funciona perfectamente ahora. Ya lo estamos usando en producción y no tenemos ningún problema con angular-cli.