web-dev-qa-db-fra.com

Comment déployer une application Angular 2 + TypeScript + systemjs?

Il existe un tutoriel de démarrage rapide sur angular.io qui utilise TypeScript et systemjs. Maintenant que je lance ce miniapp, comment pourrais-je créer quelque chose de déployable? Je n'ai trouvé aucune information à ce sujet.

Ai-je besoin d'outils supplémentaires, de paramètres supplémentaires dans System.config?

(Je sais que je pourrais utiliser webpack et créer un seul bundle.js, mais j'aimerais utiliser systemjs tel qu'il est utilisé dans le tutoriel)

Quelqu'un pourrait-il partager son processus de construction avec cette configuration (Angular 2, TypeScript, systemjs)

103
Brian G. Bell

L’essentiel à comprendre à ce niveau est qu’en utilisant la configuration suivante, vous ne pouvez pas concaténer directement des fichiers JS compilés.

A la configuration du compilateur 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"
  ]
}

Dans le HTML

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

En fait, ces fichiers JS contiendront des modules anonymes. Un module anonyme est un fichier JS qui utilise System.register mais sans le nom du module comme premier paramètre. C'est ce que le compilateur TypeScript génère par défaut lorsque systemjs est configuré en tant que gestionnaire de module.

Ainsi, pour que tous vos modules soient dans un seul fichier JS, vous devez exploiter la propriété outFile dans la configuration de votre compilateur TypeScript.

Pour ce faire, vous pouvez utiliser les éléments suivants:

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

Cela pourrait être combiné avec un autre traitement:

  • pour exagérer les fichiers TypeScript compilés
  • créer un fichier app.js
  • créer un fichier vendor.js pour des bibliothèques tierces
  • créer un fichier boot.js pour importer le module qui bootstrap l'application. Ce fichier doit être inclus à la fin de la page (lorsque toute la page est chargée).
  • mettre à jour le index.html pour prendre en compte ces deux fichiers

Les dépendances suivantes sont utilisées dans les tâches gulp:

  • ravi-concat
  • gulp-html-replace
  • gulp-TypeScript
  • avaler

Ce qui suit est un exemple pour l’adapter.

  • Créer le fichier 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'));
    });
    
  • Créer le fichier 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'));
    });
    
  • Créer le fichier boot.min.js

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

    Le config.prod.js contient simplement les éléments suivants:

     System.import('boot')
        .then(null, console.error.bind(console));
    
  • Mettre à jour le fichier 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'));
    });
    

    Le index.html ressemble à ceci:

    <html>
      <head>
        <!-- Some CSS -->
    
        <!-- build:vendor -->
        <script src="node_modules/es6-shim/es6-shim.min.js"></script>
        <script src="node_modules/systemjs/dist/system-polyfills.js"></script>
        <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
        <script src="node_modules/systemjs/dist/system.src.js"></script>
        <script src="node_modules/rxjs/bundles/Rx.js"></script>
        <script src="node_modules/angular2/bundles/angular2.dev.js"></script>
        <script src="node_modules/angular2/bundles/http.dev.js"></script>
        <!-- endbuild -->
    
        <!-- build:app -->
        <script src="config.js"></script>
        <!-- endbuild -->
      </head>
    
      <body>
        <my-app>Loading...</my-app>
    
        <!-- build:boot -->
        <!-- endbuild -->
      </body>
    </html>
    

Notez que la System.import('boot'); doit être effectuée à la fin du corps pour attendre que tous les composants de votre application soient enregistrés à partir du fichier app.min.js.

Je ne décris pas ici le moyen de gérer la minification CSS et HTML.

66
Thierry Templier

Vous pouvez utiliser la commande de construction angular2-cli

ng build -prod

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

Les constructions créées avec le drapeau - prod via ng build -prod ou ng serve -prod regroupent toutes les dépendances dans un fichier unique , et utilisez les techniques d’agitation .

Mise à jour

Cette réponse a été soumise lorsque angular2 était dans rc4

Je l'avais essayé à nouveau sur angular-cli beta21 et angular2 ^ 2.1.0 et il fonctionnait comme prévu

Cette réponse nécessite l'initialisation de l'application avec angular-cli, vous pouvez utiliser

ng new myApp

Ou sur un existant

ng init

Mise à jour 08/06/2018

Pour angular 6, la syntaxe est différente.

ng build --prod --build-optimizer

Vérifiez le documentation

28
Amr ElAdawy

Vous pouvez créer un projet Angular 2 (2.0.0-rc.1) dans TypeScript à l'aide de SystemJS avec Gulp et SystemJS-Builder .

Vous trouverez ci-dessous une version simplifiée de la construction, de la consolidation et de la consolidation de Tour of Heroes sous 2.0.0-rc.1 ( source complète , exemple en direct ).

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

system.config.js

var map = {
  'app':                                'app',
  'rxjs':                               'vendor/rxjs',
  'zonejs':                             'vendor/zone.js',
  'reflect-metadata':                   'vendor/reflect-metadata',
  '@angular':                           'vendor/@angular'
};

var packages = {
  'app':                                { main: 'main', defaultExtension: 'js' },
  'rxjs':                               { defaultExtension: 'js' },
  'zonejs':                             { main: 'zone', defaultExtension: 'js' },
  'reflect-metadata':                   { main: 'Reflect', defaultExtension: 'js' }
};

var packageNames = [
  '@angular/common',
  '@angular/compiler',
  '@angular/core',
  '@angular/http',
  '@angular/platform-browser',
  '@angular/platform-browser-dynamic',
  '@angular/router',
  '@angular/router-deprecated',
  '@angular/testing',
  '@angular/upgrade',
];

packageNames.forEach(function(pkgName) {
  packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});

System.config({
  map: map,
  packages: packages
});
12
Steely

Voici mon passe-partout MEA2N pour Angular 2: https://github.com/simonxca/mean2-boilerplate

C'est un simple passe-partout qui utilise tsc pour mettre les choses en place. (Utilise en fait grunt-ts , qui à la base est simplement la commande tsc.) Aucun Wekpack, etc. n'est nécessaire.

Que vous utilisiez ou non le grognement, l’idée est la suivante:

  • écrivez votre application dans un dossier appelé ts/ (exemple: public/ts/)
  • utilisez tsc pour mettre en miroir la structure de répertoires de votre dossier ts/ dans un dossier js/ et ne faites que référencer des fichiers du dossier js/ de votre index.html.

Pour que grunt-ts fonctionne (il devrait exister une commande équivalente pour plain tsc, Gulp, etc.), vous avez une propriété dans votre tsconfig.json appelé "outDir": "../js", et le référencer dans votre gruntfile.js avec:

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

Ensuite, exécutez grunt ts, qui prendra votre application dans public/ts/ et la reflétera sur public/js/.

Là. Super facile à comprendre. Pas la meilleure approche, mais une bonne pour commencer.

1
Simonxca

La façon la plus simple de grouper angular rc1 pour systemJs consiste à utiliser gulp et 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);
        });
});

Comme indiqué dans les commentaires, systemJs rencontre actuellement des problèmes lors du regroupement de composants à l'aide de moduleId: module.id

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

La recommandation actuelle (angular 2 rc1) semble consister à utiliser des chemins explicites, à savoir moduleId: '/app/path/'

1
paul

J'ai utilisé expressjs sur le backend pour servir mon projet ng2. Vous pouvez le vérifier depuis ma page github: https://github.com/echonax/ng2-beta-and-test-framework

0
eko

Sous le site Web Angular.io, sous la section Avancé/Déploiement, il est recommandé de déployer la méthode la plus simple consiste à "copier l'environnement de développement sur le serveur".

  1. passez par la section sous: Déploiement le plus simple possible. Les fichiers de projet finaux sont affichés dans la section de code. Notez qu'il configure déjà le code pour charger les fichiers de package npm à partir du Web (au lieu du dossier local npm_modules).

  2. assurez-vous qu'il est en cours d'exécution sur votre ordinateur local (npm start). Ensuite, dans le dossier du projet, copiez tout le contenu du sous-dossier '/ src' dans le compartiment S3 que vous avez configuré. Vous pouvez utiliser le glisser-déposer pour copier. Pendant ce processus, vous avez la possibilité de sélectionner le paramètre d'autorisation pour les fichiers. Assurez-vous de les rendre "lisibles" pour "Tout le monde".

  3. sous l'onglet "Propriétés" du compartiment, recherchez le panneau "Hébergement de site Web statique", activez l'option "Utiliser ce compartiment pour héberger le site Web", puis spécifiez "index.html" dans le document Index et le document Erreur.

  4. cliquez sur le site internet statique Endpoint, votre projet va bien!

0
Joseph Wu