Come faccio a distribuire un’app di sistema Angular 2 + Typescript +?

Esiste un tutorial su quickstart su angular.io che utilizza typescript e systemjs. Ora che ho quel miniapp in esecuzione, come potrei creare qualcosa di dispiegabile? Non sono riuscito a trovare alcuna informazione a riguardo.

Ho bisogno di strumenti aggiuntivi, eventuali impostazioni aggiuntive in System.config?

(So ​​che potrei usare webpack e creare un singolo bundle.js, ma mi piacerebbe usare systemjs come è usato nel tutorial)

Qualcuno potrebbe condividere il processo di compilazione con questa configurazione (Angular 2, TypeScript, systemjs)

La cosa fondamentale da capire a questo livello è che usando la seguente configurazione, non è ansible concatenare direttamente i file JS compilati.

Alla configurazione del compilatore 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" ] } 

Nell’HTML

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

Di fatto, questi file JS conterranno moduli anonimi. Un modulo anonimo è un file JS che utilizza System.register ma senza il nome del modulo come primo parametro. Questo è ciò che il compilatore typescript genera di default quando systemjs è configurato come module manager.

Quindi, per avere tutti i moduli in un singolo file JS, è necessario sfruttare la proprietà outFile all’interno della configurazione del compilatore TypeScript.

È ansible utilizzare il seguente gulp interno per farlo:

 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')); }); 

Questo potrebbe essere combinato con altre elaborazioni:

  • per rendere più agevoli i file TypeScript compilati
  • per creare un file app.js
  • per creare un file vendor.js per le librerie di terze parti
  • per creare un file boot.js per importare il modulo che boot.js il bootstrap dell’applicazione. Questo file deve essere incluso alla fine della pagina (quando viene caricata tutta la pagina).
  • per aggiornare index.html per tenere conto di questi due file

Le seguenti dipendenze vengono utilizzate nelle attività di Gulp:

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

Quello che segue è un esempio in modo che possa essere adattato.

  • Crea il file 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')); }); 
  • Crea il file 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')); }); 
  • Crea il file boot.min.js

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

    Il file config.prod.js contiene semplicemente quanto segue:

      System.import('boot') .then(null, console.error.bind(console)); 
  • Aggiorna il file 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')); }); 

    index.html il seguente aspetto:

                      Loading...     

Si noti che System.import('boot'); deve essere eseguito alla fine del corpo per attendere che tutti i componenti dell’app vengano registrati dal file app.min.js

Non descrivo qui il modo di gestire la minificazione CSS e HTML.

È ansible utilizzare il comando di build angular2-cli

 ng build -prod 

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

Le build create con il flag -prod tramite ng build -prod o ng serve -prod raggruppano tutte le dipendenze in un singolo file e fanno uso di tecniche di scuotimento degli alberi .

Aggiornare

Questa risposta è stata inviata quando angular2 era in rc4

L’ho provato di nuovo su angular-cli beta21 e angular2 ^ 2.1.0 e funziona come previsto

Questa risposta richiede l’inizializzazione dell’app con angular-cli che puoi utilizzare

 ng new myApp 

O su uno esistente

 ng init 

Aggiornamento 08/06/2018

Per l’angular 6 la syntax è diversa.

 ng build --prod --build-optimizer 

Controlla la documentazione

È ansible creare un progetto Angular 2 (2.0.0-rc.1) in Typescript usando SystemJS con Gulp e SystemJS-Builder .

Di seguito è riportata una versione semplificata di come creare, raggruppare e ridurre Tour of Heroes con 2.0.0-rc.1 ( full source , esempio live ).

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']); 

Ecco il mio boiler MEA2N per Angular 2: https://github.com/simonxca/mean2-boilerplate

È un semplice foglio di riscontro che usa tsc per mettere insieme le cose. (In realtà usa grunt-ts , che al suo interno è solo il comando tsc.) Non è necessario alcun Wekpack, ecc.

Se usi o no il grunt, l’idea è:

  • scrivi la tua app in una cartella chiamata ts/ (esempio: public/ts/ )
  • usa tsc per rispecchiare la struttura delle directory della tua ts/ cartella in una js/ cartella e solo i file di riferimento nella cartella js/ nel tuo index.html .

Per far funzionare grunt-ts (dovrebbe esserci un comando equivalente per plain tsc, Gulp, ecc.), Hai una proprietà nel tuo tsconfig.json chiamata "outDir": "../js" , e "outDir": "../js" riferimento a gruntfile.js con:

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

Quindi esegui grunt ts , che porterà la tua app in public/ts/ e la rispecchierà a public/js/ .

Là. Super facile da capire. Non l’approccio migliore, ma uno buono per iniziare.

Il modo più semplice che ho trovato per raggruppare rc1 angular per systemJs è usare 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); }); }); 

Come sottolineato nei commenti, systemJs ha attualmente problemi durante il raggruppamento dei componenti usando moduleId: module.id

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

L’attuale raccomandazione (angular 2 rc1) sembra essere quella di utilizzare percorsi espliciti, ad esempio moduleId: '/app/path/'

Ho usato expressjs sul backend per servire il mio progetto ng2. Puoi verificarlo dalla mia pagina github: https://github.com/echonax/ng2-beta-and-test-framework

Sotto il sito Web di Angular.io, nella sezione Avanzate / Distribuzione, è consigliabile che il modo più semplice per la distribuzione sia “copiare l’ambiente di sviluppo sul server”.

  1. passare alla sezione sotto: Implementazione più semplice ansible. I file di progetto finali sono mostrati all’interno della sezione del codice. Si noti che già imposta il codice per caricare i file del pacchetto npm dal web (invece che dalla cartella locale npm_modules).

  2. assicurati che sia in esecuzione sul tuo computer locale (inizio npm). Quindi, sotto la cartella del progetto, copia tutto nella sottocartella ‘/ src’ nel bucket S3 che hai impostato. È ansible utilizzare il trascinamento della selezione per copiare, durante tale processo, l’opzione per selezionare l’impostazione di authorization per i file, assicurarsi di renderli “leggibili” su “tutti”.

  3. sotto la scheda ‘Proprietà’ di bucket, cerca il pannello ‘Static website hosting’, seleziona ‘Usa questo bucket per ospitare il sito’, e specifica ‘index.html’ per entrambi i documenti Index e Error.

  4. fai clic sul sito web statico Endpoint, il tuo progetto sarà in esecuzione!