Angular 2 + Typescript + systemjsアプリを実際にデプロイするにはどうすればよいですか?


103

typescriptとsystemjsを使用するクイックスタートチュートリアルがangular.ioにあります。ミニアプリを実行したので、展開可能なものを作成するにはどうすればよいですか?それに関する情報はまったく見つかりませんでした。

System.configに追加のツールや追加の設定が必要ですか?

(webpackを使用して単一のbundle.jsを作成できることはわかっていますが、チュートリアルで使用されているsystemjsを使用したいと思います)

誰かがこのセットアップで構築プロセスを共有できますか(Angular 2、TypeScript、systemjs)


JSPMを使用してデプロイするng2アプリを構築するための私のレシピは次のとおりです:stackoverflow.com/a/34616199/3532945
brando

2
単純な回答ng build -prod stackoverflow.com/a/38421680/5079380
Amr ElAdawy

回答:


66

このレベルで理解する重要なことは、次の構成を使用すると、コンパイルされたJSファイルを直接連結できないことです。

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"
  ]
}

HTMLで

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

実際、これらのJSファイルには匿名モジュールが含まれます。匿名モジュールは、System.register最初のパラメーターとしてモジュール名を使用しますが、モジュール名がないJSファイルです。これは、systemjsがモジュールマネージャとして構成されている場合に、typescriptコンパイラがデフォルトで生成するものです。

したがって、すべてのモジュールを単一のJSファイルにoutFile含めるには、TypeScriptコンパイラー構成内のプロパティーを利用する必要があります。

これを行うには、次の内部gulpを使用できます。

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

これは他のいくつかの処理と組み合わせることができます:

  • コンパイルされたTypeScriptファイルを醜くする
  • app.jsファイルを作成する
  • vendor.jsサードパーティライブラリのファイルを作成する
  • boot.jsアプリケーションをブートストラップするモジュールをインポートするファイルを作成します。このファイルは、ページの最後に含める必要があります(すべてのページがロードされたとき)。
  • index.htmlこれらの2つのファイルを考慮に入れて更新するには

以下の依存関係がgulpタスクで使用されます。

  • ガク・コンキャット
  • gulp-html-replace
  • ガプタイプスクリプト
  • ガクガシ

以下はサンプルなので、適応させることができます。

  • 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'));
    });
    
  • 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'));
    });
    
  • boot.min.jsファイルを作成する

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

    config.prod.js単純に次のものが含まれます。

     System.import('boot')
        .then(null, console.error.bind(console));
    
  • 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は次のようになります。

    <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>
    

System.import('boot');すべてのアプリコンポーネントがapp.min.jsファイルから登録されるのを待つには、本文の最後でを実行する必要があることに注意してください。

ここでは、CSSおよびHTMLの縮小を処理する方法については説明しません。


1
例を使ってgithubリポジトリを作成できますか?
jdelobel

私はあなたの指示に従いましたが、gulpに関してはすべて問題ありません。しかし、ブラウザーでアプリを実行すると、次のコンソールログエラーが発生します:「system.src.js:1625 Uncaught TypeError:複数の匿名のSystem.registerが同じモジュールファイルで呼び出されています。」これが何を意味し、どのように修正するかについてのアイデアはありますか?
AngularM 2016年

@AngularM:outFileパラメータはありますか?これがエラーの鍵です;-)
Thierry Templier

私は私のgulpファイルとtsconfigにそれを持っています
AngularM

私が提出したgithubプロジェクトを見ていただけませんか?上記の私のコメントを参照してください。コードにいくつかの違いがありますか?
ティエリーテンプリエ2016年

28

angular2-cli buildコマンドを使用できます

ng build -prod

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

-prodフラグを使用して作成されたビルド、ng build -prodまたはng serve -prodすべての依存関係を単一のファイルにバンドルし、ツリーのシェイク技術を利用します

更新

この回答は、angular2がrc4にあったときに送信されました

angular-cli beta21とangular2 ^ 2.1.0でもう一度試してみましたが、期待通りに機能しています

この答えは、あなたが使用できるangular-cliでアプリを初期化することを必要とします

ng new myApp

または既存のものに

ng init

アップデート08/06/2018

角度6の場合、構文は異なります。

ng build --prod --build-optimizer

ドキュメントを確認してください


8
これには、アプリがangular-cliの独断的な構造で構成されている必要があります。
マイケルペル

2
@Amr ElAdawy FYI angular-cliがwebpackに移動しました。この質問はSystemJSに関連しています。ng buildは私にはうまくいきません。
Shahriar Hasanが

@ShahriarHasanSayeed私が回答を提出したとき、またはそれを試したときのことですか?
Amr ElAdawy 2016年

@AmrElAdawy、これが実際に機能するモジュールのバージョンを追加できますか。Angular2は7月以来かなり変更されています。
ppovoski 2016年

2
Tour of Heroesチュートリアルをcliバージョンに変換するのは簡単です。CLIを使用して新しいプロジェクトを生成し、チュートリアルファイルをコピーするだけです。
Rosdi Kasim 2016

12

あなたはとSystemJSを使用して活字体の角度2(2.0.0-rc.1)プロジェクトをビルドすることができガルプSystemJS-ビルダー

以下は、2.0.0-rc.1を実行するTour of Heroesをビルド、バンドル、および縮小する方法の簡略バージョンです(完全なソース実例)。

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


2
SystemJsとGulpの実行方法を指定していただけますか?
Jan Drozen 2016

@JanDrozen gulpfileと同じ場所で実行できます。gulp <taskname>ここで、「taskname」は、SystemJSビルダーを呼び出すタスクの名前ですbundle:app。上記の例ではです。そのGulpタスクでは、「systemjs-builder」npmモジュールを使用して、システム構成と出力ファイルを指定できます。
Steely、

@スティーリー:ありがとう!魅力のように機能します。デフォルトのターゲットが期待されます-uglify()メソッドが欠落しています(または何か欠落しています)。この最後の不明瞭な部分を説明していただけますか?
Jan Drozen 2016

@Steelyは、angular2の新しいバージョンでそれを行う方法をご案内いただけますか?
micronyks 2016

@ Steely.angular2 quickstart-appを実行するために必要な最新のangular2ビルドファイルの最終リンク(github上)を提供できますか?
micronyks 2016

1

これがAngular 2のMEA2Nボイラープレートです:https//github.com/simonxca/mean2-boilerplate

これはtsc、物事を組み立てるために使用するシンプルなボイラープレートです。(実際には、ただのコマンドであるgrunt-tsを使用しtscます。)Wekpackなどは必要ありません。

うなり声を使用するかどうかにかかわらず、アイデアは次のとおりです。

  • 名前のフォルダにアプリケーションを書くts/(例:public/ts/
  • 使用tscあなたのディレクトリ構造ミラーリングするts/にフォルダjs/内のフォルダだけ参照ファイルをjs/自分の中にフォルダindex.html

取得するには面倒-TS仕事に(など無地TSC、ガルプ、のための同等のコマンドがあるはずです)、あなたはあなたに財産を持っているtsconfig.jsonと呼ばれ"outDir": "../js"、そしてあなたにそれを参照gruntfile.jsして:

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

次にを実行しますgrunt ts。これにより、アプリが読み込まれpublic/ts/、ミラーリングされpublic/js/ます。

そこ。とてもわかりやすい。最善の方法ではありませんが、開始するには良い方法です。


1

systemJsの角度rc1をバンドルするために私が見つけた最も簡単な方法は、gulpおよびを使用すること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);
        });
});

コメントで指摘されているように、systemJは現在、コンポーネントをバンドルするときに問題があります。 moduleId: module.id

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

現在の推奨事項(angular 2 rc1)は、明示的なパスを使用することです。 moduleId: '/app/path/'


これは有望に思えますが、@Componentデコレータで外部テンプレートへの相対パスを使用すると失敗します。 bundle.js相対パスであっても絶対パスとして解決しようとするため、404エラーが発生します(stackoverflow.com/questions/37497635/…を参照)。どのように対処しましたか?
BeetleJuice 2016年

moduleId相対パスに設定していますか?
ポール

わかりません。私が持っているmoduleId: module.id@Component
ビートルジュース

これは、完全なパスを下に置くのと同じ欠点があり、そもそもtemplateUrl持っmoduleIdている目的を無効にします。推奨されているように私は相対パスを使用しようとしている(angular.io/docs/ts/latest/cookbook/...
ビートルジュース

明示的にパスを自分などを設定することで、より多くの運を持っていることmoduleId: '/app/components/home/'
ポール


0

Angular.io WebサイトのAdvanced / Deploymentセクションで、最も簡単なデプロイ方法は「開発環境をサーバーにコピーする」ことです。

  1. 「可能な最も簡単な展開」のセクションを参照してください。最終的なプロジェクトファイルは、コードセクション内に表示されます。(ローカルのnpm_modulesフォルダーからではなく)Webからnpmパッケージファイルをロードするコードがすでに設定されていることに注意してください。

  2. ローカルコンピューターで実行されていることを確認してください(npm start)。次に、プロジェクトフォルダーの下にある「/ src」サブフォルダーの下のすべてを、設定したS3バケットにコピーします。ドラッグアンドドロップを使用してコピーすることができます。そのプロセス中に、ファイルの権限設定を選択するオプションが表示されます。ファイルを「全員」に「読み取り可能」にするようにしてください。

  3. バケットの[プロパティ]タブで、[静的Webサイトホスティング]パネルを探し、[このバケットを使用してWebサイトをホストする]オプションをオンにし、インデックスドキュメントとエラードキュメントの両方に[index.html]を指定します。

  4. 静的なWebサイトのエンドポイントをクリックすると、プロジェクトが正常に実行されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.