Como faço para realmente implantar um aplicativo system_1 do Angular 2 + Typescript +?

Há um tutorial de iniciação rápida no angular.io que usa typescript e systemjs. Agora que eu tenho esse miniapp rodando, como eu poderia criar algo implantável? Eu não consegui encontrar nenhuma informação sobre isso.

Preciso de ferramentas extras, configurações adicionais no System.config?

(Eu sei que eu poderia usar o Webpack e criar um único bundle.js, mas eu gostaria de usar o systemjs como ele é usado no tutorial)

Alguém poderia compartilhar seu processo de compilation com essa configuração (Angular 2, TypeScript, systemjs)

A principal coisa para entender neste nível é que usando a seguinte configuração, você não pode concatir arquivos JS compilados diretamente.

Na configuração do compilador TypeScript:

{ "compilerOptions": { "emitDecoratorMetadata": true, "experimentalDecorators": true, "declaration": false, "stripInternal": true, "module": "system", "moduleResolution": "node", "noEmitOnError": false, "rootDir": ".", "inlineSourceMap": true, "inlineSources": true, "target": "es5" }, "exclude": [ "node_modules" ] } 

No HTML

 System.config({ packages: { app: { defaultExtension: 'js', format: 'register' } } }); 

De fato, esses arquivos JS conterão módulos anônimos. Um módulo anônimo é um arquivo JS que usa o System.register mas sem o nome do módulo como primeiro parâmetro. É o que o compilador typescript gera por padrão quando o systemjs é configurado como gerenciador de módulos.

Portanto, para ter todos os seus módulos em um único arquivo JS, você precisa aproveitar a propriedade outFile na sua configuração de compilador do TypeScript.

Você pode usar o seguinte dentro de gole para fazer isso:

 const gulp = require('gulp'); const ts = require('gulp-typescript'); var tsProject = ts.createProject('tsconfig.json', { typescript: require('typescript'), outFile: 'app.js' }); gulp.task('tscompile', function () { var tsResult = gulp.src('./app/**/*.ts') .pipe(ts(tsProject)); return tsResult.js.pipe(gulp.dest('./dist')); }); 

Isso poderia ser combinado com algum outro processamento:

  • para uglify coisas os arquivos compilados TypeScript
  • para criar um arquivo app.js
  • criar um arquivo vendor.js para bibliotecas de terceiros
  • para criar um arquivo boot.js para importar o módulo que inicializa o aplicativo. Este arquivo deve ser incluído no final da página (quando toda a página é carregada).
  • para atualizar o index.html para levar em conta esses dois arquivos

As seguintes dependencies são usadas nas tarefas de gulp:

  • gole-concat
  • gulp-html-replace
  • gulp-typescript
  • gulp-uglify

O seguinte é uma amostra para que possa ser adaptada.

  • Crie o arquivo app.min.js

     gulp.task('app-bundle', function () { var tsProject = ts.createProject('tsconfig.json', { typescript: require('typescript'), outFile: 'app.js' }); var tsResult = gulp.src('app/**/*.ts') .pipe(ts(tsProject)); return tsResult.js.pipe(concat('app.min.js')) .pipe(uglify()) .pipe(gulp.dest('./dist')); }); 
  • Crie o arquivo vendors.min.js

     gulp.task('vendor-bundle', function() { gulp.src([ 'node_modules/es6-shim/es6-shim.min.js', 'node_modules/systemjs/dist/system-polyfills.js', 'node_modules/angular2/bundles/angular2-polyfills.js', 'node_modules/systemjs/dist/system.src.js', 'node_modules/rxjs/bundles/Rx.js', 'node_modules/angular2/bundles/angular2.dev.js', 'node_modules/angular2/bundles/http.dev.js' ]) .pipe(concat('vendors.min.js')) .pipe(uglify()) .pipe(gulp.dest('./dist')); }); 
  • Crie o arquivo boot.min.js

     gulp.task('boot-bundle', function() { gulp.src('config.prod.js') .pipe(concat('boot.min.js')) .pipe(uglify()) .pipe(gulp.dest('./dist')); }); 

    O config.prod.js contém simplesmente o seguinte:

      System.import('boot') .then(null, console.error.bind(console)); 
  • Atualize o arquivo index.html

     gulp.task('html', function() { gulp.src('index.html') .pipe(htmlreplace({ 'vendor': 'vendors.min.js', 'app': 'app.min.js', 'boot': 'boot.min.js' })) .pipe(gulp.dest('dist')); }); 

    O index.html parece com o seguinte:

                      Loading...     

Observe que o System.import('boot'); deve ser feito no final do corpo para aguardar que todos os componentes do aplicativo sejam registrados a partir do arquivo app.min.js

Eu não descrevo aqui a maneira de lidar com a minificação de CSS e HTML.

Você pode usar o comando angular2-cli build

 ng build -prod 

https://github.com/angular/angular-cli/wiki/build#bundling

Construções criadas com o sinalizador -prod através de ng build -prod ou ng serve -prod todas as dependencies em um único arquivo , e fazem uso de técnicas de agitar as trees .

Atualizar

Esta resposta foi enviada quando angular2 estava em rc4

Eu tentei novamente em angular-cli beta21 e angular2 ^ 2.1.0 e está funcionando como esperado

Esta resposta requer inicializar o aplicativo com o angular-cli que você pode usar

 ng new myApp 

Ou em um já existente

 ng init 

Atualização 08/06/2018

Para angular 6, a syntax é diferente.

 ng build --prod --build-optimizer 

Verifique a documentação

Você pode criar um projeto Angular 2 (2.0.0-rc.1) em Typescript usando SystemJS com Gulp e SystemJS-Builder .

Abaixo está uma versão simplificada de como construir, empacotar e minimizar o Tour of Heroes executando 2.0.0-rc.1 ( fonte completa , exemplo ao vivo ).

gulpfile.js

 var gulp = require('gulp'); var sourcemaps = require('gulp-sourcemaps'); var concat = require('gulp-concat'); var typescript = require('gulp-typescript'); var systemjsBuilder = require('systemjs-builder'); // Compile TypeScript app to JS gulp.task('compile:ts', function () { return gulp .src([ "src/**/*.ts", "typings/*.d.ts" ]) .pipe(sourcemaps.init()) .pipe(typescript({ "module": "system", "moduleResolution": "node", "outDir": "app", "target": "ES5" })) .pipe(sourcemaps.write('.')) .pipe(gulp.dest('app')); }); // Generate systemjs-based bundle (app/app.js) gulp.task('bundle:app', function() { var builder = new systemjsBuilder('public', './system.config.js'); return builder.buildStatic('app', 'app/app.js'); }); // Copy and bundle dependencies into one file (vendor/vendors.js) // system.config.js can also bundled for convenience gulp.task('bundle:vendor', function () { return gulp.src([ 'node_modules/jquery/dist/jquery.min.js', 'node_modules/bootstrap/dist/js/bootstrap.min.js', 'node_modules/es6-shim/es6-shim.min.js', 'node_modules/es6-promise/dist/es6-promise.min.js', 'node_modules/zone.js/dist/zone.js', 'node_modules/reflect-metadata/Reflect.js', 'node_modules/systemjs/dist/system-polyfills.js', 'node_modules/systemjs/dist/system.src.js', ]) .pipe(concat('vendors.js')) .pipe(gulp.dest('vendor')); }); // Copy dependencies loaded through SystemJS into dir from node_modules gulp.task('copy:vendor', function () { gulp.src(['node_modules/rxjs/**/*']) .pipe(gulp.dest('public/lib/js/rxjs')); gulp.src(['node_modules/angular2-in-memory-web-api/**/*']) .pipe(gulp.dest('public/lib/js/angular2-in-memory-web-api')); return gulp.src(['node_modules/@angular/**/*']) .pipe(gulp.dest('public/lib/js/@angular')); }); gulp.task('vendor', ['bundle:vendor', 'copy:vendor']); gulp.task('app', ['compile:ts', 'bundle:app']); // Bundle dependencies and app into one file (app.bundle.js) gulp.task('bundle', ['vendor', 'app'], function () { return gulp.src([ 'app/app.js', 'vendor/vendors.js' ]) .pipe(concat('app.bundle.js')) .pipe(uglify()) .pipe(gulp.dest('./app')); }); gulp.task('default', ['bundle']); 

Aqui está o meu clichê do MEA2N para o Angular 2: https://github.com/simonxca/mean2-boilerplate

É um clichê simples que usa o tsc para juntar as coisas. (Na verdade, usa grunt-ts , que em seu núcleo é apenas o comando tsc.) Não é necessário Wekpack, etc.

Quer você use ou não grunhido, a ideia é:

  • escreva seu aplicativo em uma pasta chamada ts/ (example: public/ts/ )
  • use tsc para espelhar a estrutura de diretório de sua pasta ts/ em uma pasta js/ e apenas faça referência a arquivos na pasta js/ em seu index.html .

Para que os grunhidos funcionem (deve haver um comando equivalente para o tsc simples, Gulp, etc.), você tem uma propriedade em seu tsconfig.json chamada "outDir": "../js" , e referencie-a em seu gruntfile.js com:

 grunt.initConfig({ ts: { source: {tsconfig: 'app/ts/tsconfig.json'} }, ... }); 

Em seguida, execute grunt ts , o que levará seu aplicativo em public/ts/ e o espelhará para public/js/ .

Lá. Super fácil de entender. Não é a melhor abordagem, mas uma boa para começar.

A maneira mais fácil que encontrei de agrupar rc1 angular para systemJs é usar gulp e systemjs-builder :

 gulp.task('bundle', function () { var path = require('path'); var Builder = require('systemjs-builder'); var builder = new Builder('/node_modules'); return builder.bundle([ '@angular/**/*.js' ], 'wwwroot/bundle.js', { minify: false, sourceMaps: false }) .then(function () { console.log('Build complete'); }) .catch(function (err) { console.log('Build error'); console.log(err); }); }); 

Como apontado nos comentários, o systemJs atualmente tem problemas ao empacotar componentes usando moduleId: module.id

https://github.com/angular/angular/issues/6131

A recomendação atual (angular 2 rc1) parece ser usar caminhos explícitos, por exemplo, moduleId: '/app/path/'

Eu usei o expressjs no backend para servir meu projeto ng2. Você pode verificá-lo na minha página do github: https://github.com/echonax/ng2-beta-and-test-framework

No site Angular.io, na seção Avançado / Implantação, é recomendável que a maneira mais simples de implantar seja “copiar o ambiente de desenvolvimento para o servidor”.

  1. percorra a seção em: Implementação mais simples possível. Os arquivos finais do projeto são mostrados dentro da seção de código. Observe que ele já configura o código para carregar arquivos de pacote npm da Web (em vez da pasta local npm_modules).

  2. verifique se ele está sendo executado em seu computador local (npm start). Em seguida, sob a pasta do projeto, copie tudo sob a subpasta ‘/ src’ para o depósito S3 que você configurou. Você pode usar arrastar e soltar para copiar, durante esse processo, você tem a opção de selecionar a configuração de permissão para os arquivos, certifique-se de torná-los “legíveis” para “todos”.

  3. na guia “Propriedades” do compartimento, procure o painel “Local de hospedagem do site estático”, marque a opção “Usar este intervalo para hospedar o site” e especifique “index.html” para documento de índice e documento de erro.

  4. clique no ponto final do site estático, o seu projeto estará funcionando!