Comment regrouper une application Angular pour la production

Je voudrais suivre et mettre à jour dans ce fil la méthode la plus récente (et si possible la plus simple) pour combiner Angular (version 2, 4, …) pour la production sur un serveur Web en direct.

S’il vous plaît inclure la version angular dans les réponses afin que nous puissions mieux suivre quand il passe aux versions ultérieures.

    2.x, 4.x, 5.x, 6.x (TypeScript) avec CLI angular

    OneTime Setup

    • npm install -g @angular/cli
    • ng new projectFolder crée une nouvelle application

    Étape de regroupement

    • ng build --prod (exécuté en ligne de commande lorsque le répertoire est projectFolder )

      flag prod bundle pour la production (voir la documentation angular pour la liste des options incluses avec l’indicateur de production).

    • Compresser en utilisant la compression Brotli des ressources en utilisant la commande suivante

      for i in dist/*; do brotli $i; done

    les bundles sont générés par défaut à projectFolder / dist (/ $ projectFolder pour 6)

    Sortie

    Tailles avec Angular 6.1.5 avec CLI 6.1.5

    • dist/main.[hash].bundle.js Votre application dist/main.[hash].bundle.js [taille: 168 Ko pour la nouvelle application Angular CLI vide, 41 Ko compressée].
    • dist/polyfill.[hash].bundle.js les dépendances polyfill (@angular, RxJS …) intégrées [taille: 58 Ko pour la nouvelle application Angular CLI vide, 17 Ko compressés].
    • dist/index.html point d’entrée de votre application.
    • dist/inline.[hash].bundle.js .bundle.js chargeur Webpack
    • dist/style.[hash].bundle.css les définitions de style
    • ressources dist/assets copiées à partir de la configuration des ressources de la CLI angular

    Déploiement

    Vous pouvez obtenir un aperçu de votre application à l’aide de la commande ng serve --prod qui démarre un serveur HTTP local de sorte que l’application avec les fichiers de production soit accessible via http: // localhost: 4200 .

    Pour une utilisation en production, vous devez déployer tous les fichiers du dossier dist du serveur HTTP de votre choix.

    2.0.1 Final utilisant Gulp (TypeScript – Cible: ES5)


    OneTime Setup

    • npm install (exécuté dans cmd lorsque direcory est projectFolder)

    Étapes de regroupement

    • npm run bundle (exécuté dans cmd lorsque direcory est projectFolder)

      les bundles sont générés dans projectFolder / bundles /

    Sortie

    • bundles/dependencies.bundle.js [ taille: ~ 1 Mo (le plus petit possible)]
      • contient rxjs et dépendances angulars, pas les frameworks entiers
    • bundles/app.bundle.js [ taille: dépend de votre projet , le mien est ~ 0.5 MB ]
      • contient votre projet

    Structure du fichier

    • projectFolder / app / (tous les composants, directives, modèles, 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 (identique au guide de démarrage rapide , il ne montre que devDependencies et npm-scripts requirejs pour regrouper)
     { "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 (identique au guide de démarrage rapide , plus disponible)
     (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/comstackr', '@angular/core', '@angular/forms', '@angular/http', '@angular/platform-browser', '@angular/platform-browser-dynamic', '@angular/router', '@angular/router-deprecated', '@angular/testing', '@angular/upgrade', ]; // add package ensortinges 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 (montre juste la différence avec systemjs.config.json)
     var map = { 'app': 'dist/app', }; 
    • projectFolder / index.html (production) – L’ordre des balises de script est critique. Placer la balise dist-systemjs.config.js après les balises de dist-systemjs.config.js permettrait toujours au programme de s’exécuter mais le bundle de dépendances serait ignoré et les dépendances seraient chargées à partir du dossier node_modules .
           Angular     loading...              
    • projectFolder / app / boot.ts est l’endroit où se trouve le bootstrap.

    Le mieux que je puisse faire encore 🙂

    Angular 2 avec Webpack (sans configuration de la CLI)

    1- Le tutoriel par l’équipe Angular2

    L’équipe Angular2 a publié un tutoriel sur l’utilisation de Webpack

    J’ai créé et placé les fichiers du tutoriel dans un petit projet de graine GitHub . Ainsi, vous pouvez rapidement essayer le stream de travail.

    Instructions :

    • npm installer

    • npm start . Pour le developpement. Cela créera un dossier virtuel “dist” qui sera chargé à votre adresse localhost.

    • npm run build . Pour la production. “Cela créera une version de dossier physique” dist “qui peut être envoyée à un serveur Web. Le dossier dist est de 7,8 Mo mais seulement 234 Ko sont réellement nécessaires pour charger la page dans un navigateur Web.

    2 – Un kit de démarrage Webkit

    Ce kit de démarrage Webpack offre plus de fonctionnalités de test que le tutoriel ci-dessus et semble très populaire.

    Workflow de production angular 2 avec le constructeur SystemJs et gulp

    Angular.io a un tutoriel de démarrage rapide. J’ai copié ce tutoriel et étendu avec des tâches simples de gulp pour regrouper tous les éléments du dossier dist qui peut être copié sur le serveur et fonctionner comme ça. J’ai essayé d’optimiser tout pour bien fonctionner sur Jenkis CI, donc les modules_noeud peuvent être mis en cache et n’ont pas besoin d’être copiés.

    Code source avec exemple d’application sur Github: https://github.com/Anjmao/angular2-production-workflow

    Étapes vers la production

    1. Nettoyer les fichiers de caractères compilés dans les fichiers js et le dossier dist
    2. Comstackr les fichiers typescript dans le dossier de l’application
    3. Utiliser le bundler SystemJs pour regrouper tout ce qui est dans un dossier avec les hachages générés pour l’actualisation du cache du navigateur
    4. Utilisez gulp-html-replace pour remplacer les scripts index.html avec les versions groupées et les copier dans le dossier dist
    5. Tout copier à l’intérieur du dossier assets dans le dossier dist

    Node : Bien que vous puissiez toujours créer votre propre processus de génération, mais je vous recommande fortement d’utiliser angular-cli, car tous les workflows sont nécessaires et cela fonctionne parfaitement maintenant. Nous l’utilisons déjà en production et nous n’avons aucun problème avec les angles angulars.

    CLI angular 1.xx (Fonctionne avec Angular 4.xx, 5.xx)

    Cela supporte:

    • Angulaire 2.x et 4.x
    • Dernier Webpack 2.x
    • Compilateur angular AoT
    • Routage (normal et paresseux)
    • SCSS
    • Regroupement de fichiers personnalisés (actifs)
    • Outils de développement supplémentaires (configurations de test de linter, d’unité et de bout en bout)

    La configuration initiale

     ng nouveau nom de projet --routing
    

    Vous pouvez append --style=scss pour le support SASS .scss.

    Vous pouvez append --ng4 pour utiliser Angular 4 au lieu de Angular 2.

    Après avoir créé le projet, la CLI exécutera automatiquement npm install pour vous. Si vous voulez utiliser Yarn à la place ou si vous voulez simplement regarder le squelette du projet sans installation, vérifiez comment le faire ici .

    Étapes groupées

    Dans le dossier du projet:

     ng build -prod
    

    Dans la version actuelle, vous devez spécifier --aot manuellement, car il peut être utilisé en mode développement (bien que ce ne soit pas pratique à cause de la lenteur).

    Cela permet également d’effectuer une compilation AoT pour des lots encore plus petits (pas de compilateur Angular, mais un compilateur généré). Les bundles sont beaucoup plus petits avec AoT si vous utilisez Angular 4 car le code généré est plus petit.
    Vous pouvez tester votre application avec AoT en mode développement (sourcemaps, pas de minification) et AoT en exécutant ng build --aot .

    Sortie

    Le ./dist sortie par défaut est ./dist , bien qu’il puisse être modifié dans ./angular-cli.json .

    Fichiers déployables

    Le résultat de l’étape de construction est le suivant:

    (Remarque: fait référence au hachage / empreinte du contenu du fichier qui est censé être un moyen de contourner le cache, ceci est possible car Webpack écrit les balises de script par lui-même)

    • ./dist/assets
      Les fichiers copiés tels ./src/assets/** depuis ./src/assets/**
    • ./dist/index.html
      De ./src/index.html , après avoir ajouté des scripts webpack
      Le fichier de modèle source est configurable dans ./angular-cli.json
    • ./dist/inline.js
      Petit chargeur de webpack / polyfill
    • ./dist/main..bundle.js
      Le fichier principal .js contenant tous les scripts .js générés / importés
    • ./dist/styles..bundle.js
      Lorsque vous utilisez des chargeurs Webpack pour CSS, ce qui est la méthode CLI, ils sont chargés via JS ici

    Dans les versions plus anciennes, il créait également des versions compressées pour vérifier leur taille et les fichiers .map sourcemaps, mais cela ne se produit plus lorsque les utilisateurs continuent à demander de les supprimer.

    Autres fichiers

    Dans certaines autres occasions, vous pouvez trouver d’autres fichiers / dossiers indésirables:

    • ./out-tsc/
      De ./src/tsconfig.json outDir
    • ./out-tsc-e2e/
      De outDir
    • ./dist/ngfactory/
      A partir du compilateur AoT (non configurable sans tromper la CLI à partir de la bêta 16)

    À ce jour, le livre de recettes Ahead-of-Time Compilation est toujours la meilleure recette pour la production groupée. Vous pouvez le trouver ici: https://angular.io/docs/ts/latest/cookbook/aot-comstackr.html

    Mon expérience avec Angular 2 est que AoT crée les plus petites versions avec presque aucun temps de chargement. Et plus important encore, la question se pose: il suffit d’envoyer quelques fichiers en production.

    Cela semble être dû au fait que le compilateur Angular ne sera pas livré avec les versions de production car les modèles sont compilés “Ahead of Time”. Il est également très intéressant de voir votre balise de modèle HTML transformée en instructions javascript qui seraient très difficiles à décomposer dans le code HTML d’origine.

    J’ai réalisé une vidéo simple où je montre la taille de téléchargement, le nombre de fichiers, etc. pour une application Angular 2 dans la version dev vs AoT – que vous pouvez voir ici:

    https://youtu.be/ZoZDCgQwnmQ

    Vous trouverez le code source utilisé dans la vidéo ici:

    https://github.com/fintechneo/angular2-templates

      **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   Hello        Loading...    6) Now just copy your dist folder to '/www' in wamp server node need to copy node_modules in www. 

    Vous pouvez déployer votre application angular sur github aide de cli-ghpages angulars

    consultez le lien pour savoir comment déployer à l’aide de ce cli.

    le site Web déployé sera stocké dans une twig de github général

    gh-pages

    utiliser peut cloner la twig git et l’utiliser comme site statique dans votre serveur

    “Meilleur” dépend du scénario. Il y a des moments où vous ne vous souciez que du plus petit paquet unique possible, mais dans les grandes applications, vous devrez peut-être envisager un chargement paresseux. À un moment donné, il devient impossible de diffuser l’application complète en un seul lot.

    Dans ce dernier cas, Webpack est généralement le meilleur moyen car il prend en charge le fractionnement du code.

    Pour un seul bundle, je considérerais Rollup, ou le compilateur Closure si vous vous sentez courageux 🙂

    J’ai créé des échantillons de tous les bundles Angular que j’ai jamais utilisés ici: http://www.syntaxsuccess.com/viewarticle/angular-production-builds

    Le code peut être trouvé ici: https://github.com/thelgevold/angular-2-samples

    Version angular: 4.1.x

    Configurez simplement angular 4 avec webpack 3 en une minute, votre bundle ENV de développement et de production sera prêt sans aucun problème, suivez simplement le doc github ci-dessous

    https://github.com/roshan3133/angular2-webpack-starter