Como agrupar um aplicativo angular para produção

Gostaria de rastrear e atualizar neste segmento o melhor método (e talvez o mais simples) para empacotar o Angular (versão 2, 4, …) para produção em um servidor da web ao vivo.

Por favor, inclua a versão Angular nas respostas para que possamos acompanhar melhor quando ela for movida para versões posteriores.

2.x, 4.x, 5.x, 6.x (TypeScript) com CLI Angular

OneTime Setup

  • npm install -g @angular/cli
  • ng new projectFolder cria uma nova aplicação

Etapa de agrupamento

  • ng build --prod (executado na linha de comando quando o diretório for projectFolder )

    flag pacote de produtos para produção (consulte a documentação Angular para obter a lista de opções incluídas com o sinalizador de produção).

  • Comprimir usando compression Brotli os resources usando o seguinte comando

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

pacotes são gerados por padrão para projectFolder / dist (/ $ projectFolder para 6)

Saída

Tamanhos com Angular 6.1.5 com CLI 6.1.5

  • dist/main.[hash].bundle.js Seu aplicativo dist/main.[hash].bundle.js [tamanho: 168 KB para o novo aplicativo da CLI Angular vazio, 41 KB compactado].
  • dist/polyfill.[hash].bundle.js as dependencies de polyfill (@angular, RxJS …) empacotadas [tamanho: 58 KB para novo aplicativo de CLI Angular vazio, 17 KB compactado].
  • dist/index.html ponto de input da sua aplicação.
  • carregador de webpack dist/inline.[hash].bundle.js
  • dist/style.[hash].bundle.css as definições de estilo
  • resources dist/assets copiados da configuração de ativos da CLI Angular

Desdobramento, desenvolvimento

Você pode obter uma visualização de seu aplicativo utilizando o comando ng serve --prod que inicia um servidor HTTP local de forma que o aplicativo com arquivos de produção seja acessível usando http: // localhost: 4200 .

Para um uso de produção, você precisa implantar todos os arquivos da pasta dist no servidor HTTP de sua escolha.

2.0.1 Final usando Gulp (TypeScript – Target: ES5)


OneTime Setup

  • npm install (executado em cmd quando direcory é projectFolder)

Etapas de Agrupamento

  • npm run bundle (executado em cmd quando direcory é projectFolder)

    pacotes são gerados para projectFolder / bundles /

Saída

  • bundles/dependencies.bundle.js [ tamanho: ~ 1 MB (o menor possível)]
    • contém rxjs e dependencies angulares, não os frameworks completos
  • bundles/app.bundle.js [ size: depende do seu projeto , o meu é ~ 0.5 MB ]
    • contém seu projeto

Estrutura de arquivos

  • projectFolder / app / (todos os componentes, diretivas, modelos, 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 (o mesmo que o guia de início rápido , mostrado apenas devDependencies e npm-scripts necessários 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 (o mesmo que o Guia de início rápido , não está mais disponível)
 (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 (acabou de mostrar a diferença com systemjs.config.json)
 var map = { 'app': 'dist/app', }; 
  • projectFolder / index.html (produção) – A ordem das tags de script é crítica. Colocar a tag dist-systemjs.config.js após as tags do pacote ainda permitiria a execução do programa, mas o pacote node_modules dependencies seria ignorado e as dependencies seriam carregadas da pasta node_modules .
       Angular     loading...              
  • projectFolder / app / boot.ts é onde está o bootstrap.

O melhor que eu pude fazer ainda 🙂

Angular 2 com Webpack (sem configuração de CLI)

1- O tutorial da equipe Angular2

A equipe Angular2 publicou um tutorial para usar o Webpack

Eu criei e coloquei os arquivos do tutorial em um pequeno projeto semente do GitHub . Então você pode experimentar rapidamente o stream de trabalho.

Instruções :

  • npm install

  • npm start . Para desenvolvimento. Isso criará uma pasta “dist” virtual que será carregada no endereço do seu host local.

  • npm run build . Para produção. “Isso criará uma versão de pasta” dist “física que pode ser enviada para um servidor da Web. A pasta dist é 7.8MB, mas apenas 234 KB é realmente necessária para carregar a página em um navegador da web.

2 – Um kit inicial do Webkit

Este Webpack Starter Kit oferece mais alguns resources de teste do que o tutorial acima e parece bastante popular.

Fluxo de trabalho de produção angular 2 com o construtor SystemJs e gulp

Angular.io tem um tutorial de início rápido. Eu copiei este tutorial e estendi com algumas tarefas simples para empacotar tudo na pasta dist que pode ser copiada para o servidor e funcionar assim. Eu tentei otimizar tudo para funcionar bem no Jenkis CI, então node_modules pode ser armazenado em cache e não precisa ser copiado.

Código-fonte com aplicativo de amostra no Github: https://github.com/Anjmao/angular2-production-workflow

Passos para a produção

  1. Limpar typescripts compilados arquivos js e pasta dist
  2. Compile arquivos typescript dentro da pasta do aplicativo
  3. Use o bundler SystemJs para agrupar tudo na pasta dist com hashes gerados para atualização do cache do navegador
  4. Use gulp-html-replace para replace scripts index.html por versões empacotadas e copie para a pasta dist
  5. Copie tudo dentro da pasta de resources para a pasta dist

: Enquanto você sempre pode criar seu próprio processo de criação, mas eu recomendo usar o angular-cli, porque ele tem todos os streams de trabalho necessários e funciona perfeitamente agora. Já estamos usando na produção e não temos nenhum problema com o angular-cli.

CLI Angular 1.xx (Funciona com Angular 4.xx, 5.xx)

Isso suporta:

  • Angular 2.xe 4.x
  • Últimas Webpack 2.x
  • Compilador Angular AoT
  • Roteamento (normal e preguiçoso)
  • SCSS
  • Agrupamento de arquivo customizado (ativos)
  • Ferramentas de desenvolvimento adicionais (linter, unidade e configurações de teste de ponta a ponta)

Configuração inicial

 ng novo nome do projeto --routing

Você pode adicionar --style=scss para suporte a SASS.

Você pode adicionar --ng4 para usar Angular 4 em vez de Angular 2.

Depois de criar o projeto, a CLI executará automaticamente a npm install para você. Se você quiser usar o Yarn, ou apenas quiser ver o esqueleto do projeto sem instalar, verifique como fazer isso aqui .

Etapas do pacote

Dentro da pasta do projeto:

 ng build -prod

Na versão atual, você precisa especificar --aot manualmente, porque ela pode ser usada no modo de desenvolvimento (embora isso não seja prático devido à lentidão).

Isso também executa a compilation AoT para pacotes ainda menores (nenhum compilador Angular, em vez disso, gerou saída do compilador). Os pacotes são muito menores com o AoT se você usar o Angular 4, pois o código gerado é menor.
Você pode testar seu aplicativo com o AoT no modo de desenvolvimento (sourcemaps, sem minification) e AoT executando ng build --aot .

Saída

O diretório de saída padrão é ./dist , embora possa ser alterado em ./angular-cli.json .

Arquivos Implantáveis

O resultado da etapa de construção é o seguinte:

(Nota: refere-se a hash / impressão digital do conteúdo do arquivo que deve ser uma forma de impedimento de cache, isso é possível já que o Webpack grava as tags de script por si só)

  • ./dist/assets
    Arquivos copiados como são de ./src/assets/**
  • ./dist/index.html
    De ./src/index.html , depois de adicionar scripts de webpack a ele
    O arquivo de modelo de origem é configurável em ./angular-cli.json
  • ./dist/inline.js
    Carregador pequeno para webpack / com polyfill
  • ./dist/main..bundle.js
    O arquivo .js principal contendo todos os scripts .js gerados / importados
  • ./dist/styles..bundle.js
    Quando você usa loaders Webpack para CSS, que é o jeito CLI, eles são carregados via JS aqui

Em versões mais antigas, ele também criava versões gzipadas para verificar seu tamanho e .map sourcemaps, mas isso não está mais acontecendo, pois as pessoas continuavam pedindo para removê-las.

Outros arquivos

Em outras ocasiões, você pode encontrar outros arquivos / pastas indesejados:

  • ./out-tsc/
    De ./src/tsconfig.json outDir
  • ./out-tsc-e2e/
    Do ./e2e/tsconfig.json de outDir
  • ./dist/ngfactory/
    Do compilador AoT (não configurável sem bifurcar o CLI a partir do beta 16)

A partir de hoje, ainda acho o livro de receitas de compilation Ahead of Time como a melhor receita para o pacote de produção. Você pode encontrá-lo aqui: https://angular.io/docs/ts/latest/cookbook/aot-compiler.html

Minha experiência com o Angular 2 até agora é que o AoT cria as menores construções com quase nenhum tempo de carregamento. E o mais importante como a questão aqui é sobre – você só precisa enviar alguns arquivos para produção.

Isso parece ser porque o compilador Angular não será fornecido com as compilações de produção, pois os modelos são compilados “Ahead of Time”. Também é muito legal ver sua marcação de modelo HTML transformada em instruções de javascript que seriam muito difíceis de fazer engenharia reversa no HTML original.

Fiz um vídeo simples em que demonstrei o tamanho do download, o número de arquivos, etc., para um aplicativo Angular 2 no dev x build AoT – que você pode ver aqui:

https://youtu.be/ZoZDCgQwnmQ

Você encontrará o código-fonte usado no vídeo aqui:

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. 

Você pode implantar seu aplicativo angular no github usando cli-ghpages angulares

confira o link para descobrir como implantar usando esse cli.

o site implantado será armazenado em algum ramo no github tipicamente

páginas de gh

use pode clonar o ramo git e usá-lo como site estático no seu servidor

“Melhor” depende do cenário. Há momentos em que você só se preocupa com o menor pacote possível, mas em aplicativos grandes talvez seja necessário considerar o carregamento lento. Em algum momento, torna-se impraticável veicular todo o aplicativo como um único pacote.

Neste último caso, o Webpack é geralmente o melhor caminho, uma vez que suporta a divisão de código.

Para um único pacote eu consideraria Rollup, ou o compilador Closure se você estiver se sentindo corajoso 🙂

Eu criei amostras de todos os empacotadores angulares que eu já usei aqui: http://www.syntaxsuccess.com/viewarticle/angular-production-builds

O código pode ser encontrado aqui: https://github.com/thelgevold/angular-2-samples

Versão angular: 4.1.x

Basta configurar o angular 4 com o webpack 3 em um minuto. Seu pacote ENV de desenvolvimento e produção ficará pronto sem qualquer problema, basta seguir o abaixo github doc

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

Intereting Posts