publicar - servidor para angular
Cómo agrupar una aplicación angular para producción (11)
¿Cuál es el mejor método para agrupar Angular (versión 2, 4, 6, ...) para la producción en un servidor web en vivo?
Incluya la versión angular en las respuestas para que podamos realizar un mejor seguimiento cuando se mueva a versiones posteriores.
Angular CLI 1.xx (Funciona con Angular 4.xx, 5.xx)
Esto apoya:
- Angular 2.xy 4.x
- Webpack 2.x más reciente
- Compilador angular de AoT
- Enrutamiento (normal y perezoso)
- SCSS
- Paquete personalizado de archivos (activos)
- Herramientas de desarrollo adicionales (linter, unidad y configuraciones de prueba de extremo a extremo)
Configuración inicial
ng new project-name --routing
Puede agregar
--style=scss
para el
--style=scss
de SASS .scss.
Puede agregar
--ng4
para usar Angular 4 en lugar de Angular 2.
Después de crear el proyecto, la CLI ejecutará automáticamente
npm install
para usted.
Si desea utilizar Yarn en su lugar, o simplemente quiere ver el esqueleto del proyecto sin instalar,
consulte aquí cómo hacerlo
.
Pasos del paquete
Dentro de la carpeta del proyecto:
ng build -prod
En la versión actual, debe especificar
--aot
manualmente, porque puede usarse en modo de desarrollo (aunque eso no es práctico debido a la lentitud).
Esto también realiza la compilación de AoT para paquetes aún más pequeños (sin compilador angular, en cambio, genera la salida del compilador).
Los paquetes son mucho más pequeños con AoT si usa Angular 4 ya que el código generado es más pequeño.
Puede probar su aplicación con AoT en modo de desarrollo (mapas de origen, sin minificación) y AoT ejecutando
ng build --aot
.
Salida
El directorio de salida predeterminado es
./dist
, aunque se puede cambiar en
./angular-cli.json
.
Archivos desplegables
El resultado del paso de compilación es el siguiente:
(Nota:
<content-hash>
refiere al hash / huella digital del contenido del archivo que pretende ser una forma de reventar el caché, esto es posible ya que Webpack escribe las etiquetas del
script
por sí mismo)
-
./dist/assets
Archivos copiados tal cual de./src/assets/**
-
./dist/index.html
Desde./src/index.html
, después de agregarle scripts webpack
El archivo de plantilla de origen es configurable en./angular-cli.json
-
./dist/inline.js
Cargador webpack pequeño / polyfill -
./dist/main.<content-hash>.bundle.js
El archivo .js principal que contiene todos los scripts .js generados / importados -
./dist/styles.<content-hash>.bundle.js
Cuando utiliza cargadores Webpack para CSS, que es la forma de CLI, aquí se cargan a través de JS
En versiones anteriores también creaba versiones comprimidas para verificar su tamaño y archivos de mapas de origen
.map
, pero esto ya no sucede ya que la gente seguía pidiendo eliminarlos.
Otros archivos
En otras ocasiones, puede encontrar otros archivos / carpetas no deseados:
-
./out-tsc/
Desde./src/tsconfig.json
outDir
-
./out-tsc-e2e/
Desde./e2e/tsconfig.json
outDir
-
./dist/ngfactory/
Desde el compilador de AoT (no configurable sin bifurcar la CLI a partir de beta 16)
2.0.1 Final
usando Gulp (TypeScript - Target: ES5)
Configuración de una sola vez
-
npm install
(ejecuta en cmd cuando directorio es projectFolder)
Pasos de empaquetado
-
npm run bundle
(se ejecuta en cmd cuando el directorio es projectFolder)los paquetes se generan para projectFolder / bundles /
Salida
-
bundles/dependencies.bundle.js
[ tamaño: ~ 1 MB (lo más pequeño posible)]- contiene rxjs y dependencias angulares, no todo el framework
-
bundles/app.bundle.js
[ tamaño: depende de su proyecto , el mío es ~ 0.5 MB ]- contiene tu proyecto
Estructura de archivo
- projectFolder / app / (todos los componentes, directivas, plantillas, etc.)
- projectFolder / gulpfile.js
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);
});
});
- projectFolder / package.json (igual que la guía de inicio rápido , que se muestra devDependencies y npm-scripts necesarios para agrupar)
{
"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"
}
}
- projectFolder / systemjs.config.js (igual que la guía de inicio rápido , ya no está disponible allí)
(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);
- projetcFolder / dist-systemjs.config.js (solo se muestra la diferencia con systemjs.config.json)
var map = {
''app'': ''dist/app'',
};
-
projectFolder / index.html
(producción):
el orden de las etiquetas de script es crítico.
Colocar la etiqueta
dist-systemjs.config.js
después de las etiquetas del paquete aún permitiría que el programa se ejecute, pero el paquete de dependencia se ignoraría y las dependencias se cargarían desde la carpetanode_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>
- projectFolder / app / boot.ts es donde está el bootstrap.
Lo mejor que pude hacer todavía :)
Angular 2 con Webpack (sin configuración de CLI)
1- El tutorial del equipo de Angular2.
El equipo de Angular2 publicó un tutorial para usar Webpack
Creé y coloqué los archivos del tutorial en un pequeño proyecto semilla de GitHub . Para que pueda probar rápidamente el flujo de trabajo.
Instrucciones :
-
npm install
-
npm start . Para desarrollo. Esto creará una carpeta virtual "dist" que se volverá a cargar en vivo en su dirección de host local.
-
npm ejecutar compilación . Para la producción. "Esto creará una versión física de la carpeta" dist "que se puede enviar a un servidor web. La carpeta dist es de 7.8MB pero solo se requieren 234KB para cargar la página en un navegador web.
2 - Un kit de inicio de Webkit
Este paquete de inicio Webpack ofrece algunas características de prueba más que el tutorial anterior y parece bastante popular.
2.x, 4.x, 5.x, 6.x, 7.x, 8.x
(TypeScript) con CLI angular
Configuración de una sola vez
-
npm install -g @angular/cli
-
ng new projectFolder
crea una nueva aplicación
Paso de agrupación
-
ng build --prod
(se ejecuta en la línea de comando cuando el directorio esprojectFolder
)paquete
prod
bandera para producción (consulte la documentación angular para la lista de opciones incluidas con la bandera de producción). -
Comprimir usando Brotli comprimir los recursos usando el siguiente comando
for i in dist/*; do brotli $i; done
los paquetes se generan por defecto en projectFolder / dist (/ $ projectFolder para 6)
Salida
Tamaños con Angular
8.3.3
con CLI
8.3.3
y opción CSS sin enrutamiento angular
-
dist/main-[es-version].[hash].js
Su aplicación incluida [tamaño ES5: 183 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 comprimido]. -
dist/index.html
punto de entrada de su aplicación. -
dist/runtime-[es-version].[hash].bundle.js
.bundle.js cargador dedist/runtime-[es-version].[hash].bundle.js
web -
dist/style.[hash].bundle.css
las definiciones de estilo -
recursos
dist/assets
copiados de la configuración de activos de Angular CLI
Despliegue
Puede obtener una vista previa de su aplicación utilizando el comando
ng serve --prod
que inicia un servidor HTTP local de modo que se pueda acceder a la aplicación con archivos de producción utilizando
http: // localhost: 4200
.
Para un uso de producción, debe implementar todos los archivos de la carpeta
dist
en el servidor HTTP que elija.
Flujo de trabajo de producción de Angular 2 con SystemJs Builder y Gulp
Angular.io tiene un tutorial de inicio rápido. Copié este tutorial y lo extendí con algunas tareas simples para agrupar todo en la carpeta dist que se puede copiar al servidor y funcionar así. Intenté optimizar todo para que funcione bien en Jenkis CI, por lo que node_modules se puede almacenar en caché y no es necesario copiar.
Código fuente con aplicación de muestra en Github: https://github.com/Anjmao/angular2-production-workflow
Pasos para la produccion- Archivos de texto limpios compilados archivos js y carpeta dist
- Compilar archivos mecanografiados dentro de la carpeta de la aplicación
- Use el paquete SystemJs para agrupar todo en la carpeta dist con hashes generados para la actualización de la memoria caché del navegador
- Use gulp-html-replace para reemplazar los scripts index.html con versiones incluidas y copie a la carpeta dist
- Copie todo dentro de la carpeta de activos a la carpeta dist
Nodo : aunque siempre puede crear su propio proceso de compilación, le recomiendo utilizar angular-cli, porque tiene todos los flujos de trabajo necesarios y ahora funciona perfectamente. Ya lo estamos usando en producción y no tenemos ningún problema con angular-cli.
"Mejor" depende del escenario. Hay momentos en los que solo te importa el paquete individual más pequeño posible, pero en aplicaciones grandes es posible que tengas que considerar la carga diferida. En algún momento, resulta poco práctico servir toda la aplicación como un solo paquete.
En este último caso, Webpack es generalmente la mejor manera, ya que admite la división de código.
Para un solo paquete, consideraría Rollup o el compilador de Closure si te sientes valiente :-)
He creado muestras de todos los paquetes angulares que he usado aquí: http://www.syntaxsuccess.com/viewarticle/angular-production-builds
El código se puede encontrar aquí: https://github.com/thelgevold/angular-2-samples
Versión angular: 4.1.x
A día de hoy todavía encuentro el libro de cocina de compilación anticipada como la mejor receta para la producción en paquete. Puede encontrarlo aquí: https://angular.io/docs/ts/latest/cookbook/aot-compiler.html
Mi experiencia con Angular 2 hasta ahora es que AoT crea las compilaciones más pequeñas casi sin tiempo de carga. Y lo más importante, ya que la pregunta aquí es: solo necesita enviar algunos archivos a producción.
Esto parece deberse a que el compilador Angular no se enviará con las compilaciones de producción, ya que las plantillas se compilan "por adelantado". También es genial ver el marcado de su plantilla HTML transformado en instrucciones de JavaScript que serían muy difíciles de aplicar ingeniería inversa en el HTML original.
Hice un video simple donde demuestro el tamaño de descarga, la cantidad de archivos, etc. para una aplicación Angular 2 en desarrollo vs AoT build, que puede ver aquí:
Encontrará el código fuente utilizado en el video aquí:
Intente debajo del comando CLI en el directorio actual del proyecto. Creará un paquete de carpetas dist. para que pueda cargar todos los archivos dentro de la carpeta dist para implementaciones.
ng build --prod --aot --base-href.
Puede implementar su aplicación angular en
github
usando
angular-cli-ghpages
mira el enlace para encontrar cómo implementar usando este cli.
el sitio web implementado se almacenará en alguna sucursal en
github
típicamente
gh-pages
use puede clonar la rama git y usarla como sitio web estático en su servidor
Simplemente configure angular 4 con webpack 3 en un minuto, su paquete ENV de desarrollo y producción estará listo sin ningún problema, solo siga el siguiente documento de github
**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.