Angularアプリを本番環境にバンドルする方法


353

Angular(バージョン2、4、6、...)をライブWebサーバーでの運用にバンドルするための最良の方法は何ですか。

Angularのバージョンを回答に含めてください。これにより、今後のリリースに移行したときに追跡しやすくなります。


とりあえず(rc1)。以下にいくつかのソリューションを示します 。stackoverflow.com/questions/37324511/how-to-bundle-angular2-rc1-with-systemjs
Pat M


RC3今40〜約300+からの要求の数を下げるバンドルされたファイルのバージョンを提供しています
パットM

2
ねえ。私はまた、WebPackを嫌い、一般的に手順をビルドします。単純なWebサイトをまとめようとするだけの、やりすぎのようなものです。したがって、私はこれを作りました:github.com/schungx/angular2-bundle
Stephen Chung

スティーブンありがとう。これは、ベンダーの部分にとっては単純なソリューションになります。これが正式に提供および更新されることを願っています。プロジェクトのファイルにGulpなどを使用していると思いますか?
Pat M

回答:


362

2.x, 4.x, 5.x, 6.x, 7.x, 8.x, 9.x (TypeScript)Angular CLI

ワンタイムセットアップ

  • npm install -g @angular/cli
  • ng new projectFolder 新しいアプリケーションを作成します

結束ステップ

  • ng build --prod(ディレクトリがのときにコマンドラインで実行projectFolder

    prodプロダクション用のフラグバンドル(プロダクションフラグに含まれるオプションのリストについては、Angularのドキュメントを参照してください)。

  • Brotliを使用して圧縮します次のコマンドを使用してリソースを圧縮します

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

バンドルはデフォルトでprojectFolder / dist(/ $ projectFolder for 6)に生成されます

出力

Angularルーティングなしの9.0.0CLI 9.0.1とオプションCSSを使用したAngularのサイズ

  • dist/main-[es-version].[hash].jsバンドルされているアプリケーション[ES5サイズ:新しいAngular CLIアプリケーションの場合は158 KB、空の40 KB圧縮]。
  • dist/polyfill-[es-version].[hash].bundle.jsバンドルされたポリフィルの依存関係(@ angular、RxJS ...)[ES5サイズ:新しいAngular CLIアプリケーションが空の場合は127 KB、37 KBの圧縮]。
  • dist/index.html アプリケーションのエントリポイント。
  • dist/runtime-[es-version].[hash].bundle.js ウェブパックローダー
  • dist/style.[hash].bundle.css スタイル定義
  • dist/assets Angular CLIアセット構成からコピーされたリソース

配備

ng serve --prodローカルHTTPサーバーを起動するコマンドを使用して、アプリケーションのプレビューを取得できます。これにより、本番ファイルを含むアプリケーションにhttp:// localhost:4200を使用してアクセスできます。

本番環境で使用distする場合は、選択したHTTPサーバーのフォルダーからすべてのファイルをデプロイする必要があります。


npm install -g angular-cli @ webpackを実行するとエラーが発生しました:npm ERR!サポートリクエストには次のファイルを含めてください:.... \ npm-debug.log。何が起こっているのか知っていますか?
Chong Wang

2
@chrismarxは、すべてのコンポーネントとそのHTMLおよびスタイルを含む1つのバンドルのみを生成します。
Nicolas Henneaux 2016

4
アプリケーションがあり、この方法を使用したいので、プロジェクトフォルダーからng initを起動します。残りの手順を実行しましたが、アプリケーションをデプロイすると、空のようです。表示されるのは「アプリの動作」だけです。メッセージ、アプリファイルを取得する場所を設定する必要がある場所はありますか?
mautrok 2016年

2
ng-initがAngular CLIから削除されました。github.com/angular/angular-cli/issues/5176
Pat M

2
ようやくこれを承認済みの回答としてマークしました。他のソリューションも同様に機能し、さらに柔軟性を提供する場合があります(CLIなしでWebpackを使用する方法について投稿しました)。Angular CLIを使用すると、間違いなく頭痛の種が少なくなります。最終的にはAngular CLIを使用してプロジェクトを調整し、AoTをより簡単に使用できるようにしました。
Pat M

57

2.0.1 Final Gulpの使用(TypeScript-ターゲット:ES5)


ワンタイムセットアップ

  • npm install (ディレクトリがprojectFolderの場合、cmdで実行されます)

バンドル手順

  • npm run bundle (ディレクトリがprojectFolderの場合、cmdで実行されます)

    バンドルはprojectFolder / bundles /に生成されます

出力

  • bundles/dependencies.bundle.js[ サイズ:〜1 MB(できるだけ小さい)]
    • フレームワーク全体ではなく、rxjsと角度依存関係が含まれています
  • bundles/app.bundle.js[ サイズ:プロジェクトによって異なりますが、私のプロジェクト0.5 MB以下です ]
    • あなたのプロジェクトが含まれています

ファイル構造

  • projectFolder / app /(すべてのコンポーネント、ディレクティブ、テンプレートなど)
  • 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);
    });
});

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

(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.jssystemjs.config.jsonとの違いを示したところ)

var map = {
    'app':                        'dist/app',
  };
  • projectFolder / index.html(製品)- スクリプトタグの順序は重要です。dist-systemjs.config.jsバンドルタグの後にタグを配置してもプログラムは実行できますが、依存関係のバンドルは無視され、依存関係はnode_modulesフォルダーから読み込まれます。

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <base href="/"/>
  <title>Angular</title>
  <link rel="stylesheet" type="text/css" href="style.css"/>
</head>
<body>

<my-app>
  loading...
</my-app>

<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>

<script src="node_modules/zone.js/dist/zone.min.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.js"></script>

<script src="dist-systemjs.config.js"></script>
<!-- Project Bundles. Note that these have to be loaded AFTER the systemjs.config script -->
<script src="bundles/dependencies.bundle.js"></script>
<script src="bundles/app.bundle.js"></script>

<script>
    System.import('app/boot').catch(function (err) {
      console.error(err);
    });
</script>
</body>
</html>
  • projectFolder / app / boot.tsは、ブートストラップがある場所です。

私がまだできる最高の:)


2
こんにちは、gulpスクリプトがバンドルを作成していますが、boot.tsファイルに何を含めればよいかわかりません。すべてのファイルがバンドルに含まれていませんか?バンドルを実行しますか?
chrismarx 2016

2
ええと、私はもう一度試す必要があると思います。私はbuilder.buildStaticに切り替えてみたところ、rxjsからcommonjsまたはamdモジュールとして読み込まれていないというエラーが発生しました。私はあなたの提案をもう一度試みます
chrismarx

1
また、バンドルがこのセットアップで実際にどのように使用されるのかわかりませんか?ここで@chrismarxとまったく同じ問題が発生しているようです。バンドルを作成することはできますが、トランスパイルされてコピーされたappフォルダー(dist / appにあります)からすべてがまだロードされているようです。ネットワークパネルを見ると、app.bundle.jsからのアプリ関連のすべてではなく、アプリ関連のファイル(コンポーネントなど)が実際にそこから読み込まれていることがわかります。A_Singh、boot.tsを共有できますか?私はここに何かが足りないようで、いくつかの説明が大好きです。
jbgarr

1
A_シン、それがどのように役立つかわかりません。ときにinline-templates実行され、それはその後、テンプレートをインラインで、すべてのアプリのフォルダとファイルのコピーを作成しますdist/app。次に、ルートとしてフォルダを使用する場合、存在しないフォルダdist-systemjs.config.jsをマッピングappします。フォルダーからアプリを実行しませんか?その場合、ルートフォルダーにネストされたフォルダーはありません。私はここで何か他のものを逃しているに違いない。フォルダーにある通常のファイルではなく、バンドルされたファイルを使用するようにsystemjsに指示する必要はありませんか?dist/appdistdistdistdistdist/app
jbgarr

1
ソリューションで問題が発生しました。ブートはここに存在しないものであり、「アプリ」に置き換えると、「モジュールが定義されていません」というエラーが発生します。
LoïcR

22

Angular 2 with Webpack(CLIセットアップなし)

1- Angular2チームによるチュートリアル

Angular2チームは、Webpackを使用するためのチュートリアルを公開しました

チュートリアルのファイルを作成して、小さなGitHubシードプロジェクトに配置しました。そのため、ワークフローをすぐに試すことができます。

手順

  • npmインストール

  • npm start。開発用。これにより、ローカルホストアドレスでライブリロードされる仮想「dist」フォルダーが作成されます。

  • npm run buildを実行します。生産用。「これにより、Webサーバーに送信できる物理的な「dist」フォルダーバージョンが作成されます。distフォルダーは7.8MBですが、実際にはWebブラウザーでページをロードするために必要なのは234KBだけです。

2-Webkitスターターキット

このWebpackスターターキットは、上記のチュートリアルよりも多くのテスト機能を提供し、非常に人気があるようです。


こんにちは、シードプロジェクトを角度2.1.0で更新することは可能ですか?チュートリアルでは現在角度2.1.0を使用しています。私はそれに続き、それを機能させることができませんでした。エラーはhttp 404です-app.component.htmlが見つかりません。
heq99 2016年

私は問題なくangular 2.1.0にアップデートしました。app.component.htmlはapp.component.ts(templateUrl: './app.component.html')から呼び出されます。同じappフォルダーに両方のファイルがありますか?
Pat M

1
ツリーの揺れ、縮小、Gzip圧縮により、生産に行くときにサイズを大幅に削減できます。ここに例を挙げた優れた記事があります。blog.mgechev.com
2016/06/26 /

16

SystemJsビルダーとgulpを使用したAngular 2の制作ワークフロー

Angular.ioにはクイックスタートチュートリアルがあります。私はこのチュートリアルをコピーし、すべてをdistフォルダーにバンドルするためのいくつかの単純なgulpタスクで拡張しました。distフォルダーはサーバーにコピーでき、同じように機能します。Jenkis CIで適切に機能するようにすべてを最適化しようとしたので、node_modulesをキャッシュでき、コピーする必要はありません。

Githubのサンプルアプリのソースコード:https : //github.com/Anjmao/angular2-production-workflow

生産へのステップ
  1. typescriptsでコンパイルされたjsファイルとdistフォルダーをクリーンアップ
  2. アプリフォルダー内でtypescriptファイルをコンパイルする
  3. SystemJs bundlerを使用して、ブラウザーキャッシュの更新用に生成されたハッシュを含むすべてをdistフォルダーにバンドルします
  4. gulp-html-replaceを使用して、index.htmlスクリプトをバンドルバージョンに置き換え、distフォルダーにコピーします
  5. アセットフォルダー内のすべてをdistフォルダーにコピーします

ノード:いつでも独自のビルドプロセスを作成できますが、必要なワークフローがすべてあり、現在は完全に機能するため、angular-cliを使用することを強くお勧めします。すでに本番環境で使用しており、angular-cliにはまったく問題はありません。


これは私が探しているものです。githubのサンプルアプリはとても便利です。ありがとう
Shahriar Hasan Sayeed

14

Angular CLI 1.xx(Angular 4.xx、5.xxで動作)

これは以下をサポートします:

  • Angular 2.xおよび4.x
  • 最新のWebpack 2.x
  • Angular AoTコンパイラ
  • ルーティング(通常および遅延)
  • SCSS
  • カスタムファイルバンドル(アセット)
  • 追加の開発ツール(リンター、ユニット、エンドツーエンドのテストセットアップ)

初期設定

ng new project-name --routing

--style=scssSASS .scssサポートを追加できます。

--ng4Angular 2の代わりにAngular 4を使用するために追加できます。

プロジェクトを作成すると、CLIが自動的に実行さnpm installれます。代わりにYarnを使用する場合、またはインストールせずにプロジェクトのスケルトンを確認する場合は、ここでその方法を確認してください

バンドル手順

プロジェクトフォルダ内:

ng build -prod

現在のバージョン--aotでは、開発モードで使用できるため、手動で指定する必要があります(ただし、速度が遅いため、これは実用的ではありません)。

これは、さらに小さなバンドル(Angularコンパイラではなく、生成されたコンパイラ出力)のAoTコンパイルも実行します。生成されたコードが小さいため、Angular 4を使用する場合、バンドルはAoTでははるかに小さくなります。
次のコマンドを実行すると、開発モードのAoT(ソースマップ、縮小なし)とAoTでアプリをテストできます。ng build --aot

出力

デフォルトの出力ディレクトリはですが./dist、で変更できます./angular-cli.json

展開可能なファイル

ビルドステップの結果は次のとおりです。

(注:<content-hash>キャッシュの無効化を意図したファイルの内容のハッシュ/フィンガープリントを指します。Webpackがscriptタグを単独で書き込むため、これは可能です)

  • ./dist/assets
    そのままコピーされたファイル ./src/assets/**
  • ./dist/index.html
    から./src/index.html、webpackスクリプトを追加した後、
    ソーステンプレートファイルは./angular-cli.json
  • ./dist/inline.js
    小型ウェブパックローダー/ポリフィル
  • ./dist/main.<content-hash>.bundle.js
    生成/インポートされたすべての.jsスクリプトを含むメインの.jsファイル
  • ./dist/styles.<content-hash>.bundle.js
    CLIの方法であるCSSにWebpackローダーを使用すると、JS経由でロードされます。

古いバージョンでは、サイズをチェックするためのgzip圧縮されたバージョンと.mapsourcemapsファイルも作成していましたが、人々がこれらを削除するように要求し続けたため、これはもう起こりません。

その他のファイル

他の特定の状況では、他の不要なファイル/フォルダーが見つかることがあります。

  • ./out-tsc/
    以下から./src/tsconfig.jsonoutDir
  • ./out-tsc-e2e/
    以下から./e2e/tsconfig.jsonoutDir
  • ./dist/ngfactory/
    AoTコンパイラーから(ベータ16以降、CLIをフォークしないと構成できません)

私のアプリからangular libとそれらの依存関係を分離することは可能ですか?
Dominick Piganell 2016

ツリーシェイクが機能するためのCLIを使用しない。これにより、アプリケーションで使用されていないすべてのAngular EcmaScriptモジュールが削除されます。速度を上げるために開発モードでこれを無効にする計画があります(「DLL」としてロードされるライブラリを呼び出します)が、最終的に分離する計画はありません。CLIを使用せずに独自のWebpackをローリングしている場合は、達成できるはずです。
Meligy

distフォルダーを使用してアプリを確認する方法。Webサーバーでホストするにはどうすればよいですか?
raj m 2017

サーバーにコピーするだけです。それはとにかく提供することができるプレーンな静的ウェブサイトです。あなたは、ルーティングを使用する場合は、サーバー構成セクションにそのチェック角度展開docssのために、かかわらず、HTMLファイルへのすべてのコールをリダイレクトすることがありますangular.io/docs/ts/latest/guide/...
Meligy

@Meligy製品<content-hash>のバンドルから削除した場合はどうなりますか。最新のバンドルの取得で問題が発生する可能性がありますか?
k11k2

5

今日、私はまだAhead-of-Time Compilationクックブックをプロダクションバンドリングの最良のレシピとして見つけています。あなたはここでそれを見つけることができます:https//angular.io/docs/ts/latest/cookbook/aot-compiler.html

これまでのところ、Angular 2を使用した経験では、AoTはロード時間がほとんどなく、最小のビルドを作成します。そして、ここでの質問が最も重要なのは、いくつかのファイルを本番環境に送るだけでよいということです。

これは、テンプレートが「Ahead of Time」でコンパイルされるため、Angularコンパイラが製品ビルドに同梱されないためであると思われます。HTMLテンプレートのマークアップが、元のHTMLにリバースエンジニアリングするのが非常に難しいJavaScript命令に変換されるのを見るのも非常にクールです。

開発サイズとAoTビルドのAngular 2アプリのダウンロードサイズ、ファイル数などを示す簡単なビデオを作成しました。

https://youtu.be/ZoZDCgQwnmQ

ビデオで使用されているソースコードはここにあります:

https://github.com/fintechneo/angular2-templates


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

    <html>
    <head>
        <title>Hello</title>

        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta charset="utf-8" />

       <link rel="stylesheet" href="app/css/styles.min.css" />   
       <script type="text/javascript" src="app/shims.js"></script>  
       <base href="https://stackoverflow.com/">
    </head>
     <body>
    <my-app>Loading...</my-app>
     <script type="text/javascript" src="app/app_libs_bundle.js"></script> 
    </body>

    </html>

 6) Now just copy your dist folder to '/www' in wamp server node need to copy node_modules in www.

2

angular-cli-ghpagesgithubを使用し て角度アプリケーションをデプロイできます

このCLIを使用してデプロイする方法を見つけるには、リンクを確認してください。

デプロイされたWebサイトはgithub通常、いくつかのブランチに保存されます

gh-ページ

使用するとgitブランチのクローンを作成し、サーバーの静的Webサイトのように使用できます


1

「最高」はシナリオによって異なります。可能な限り最小の単一バンドルのみを気にする場合がありますが、大きなアプリでは遅延読み込みを検討する必要がある場合があります。ある時点で、アプリ全体を単一のバンドルとして提供することが実用的でなくなります。

後者の場合、コード分割をサポートするため、Webpackが一般的に最良の方法です。

単一のバンドルについては、Rollup、または勇気を感じている場合はClosureコンパイラを検討します:-)

ここで使用したすべてのAngularバンドルのサンプルを作成しました:http ://www.syntaxsuccess.com/viewarticle/angular-production-builds

コードはここにあります:https : //github.com/thelgevold/angular-2-samples

Angularバージョン:4.1.x



0

現在のプロジェクトディレクトリで以下のCLIコマンドを試してください。distフォルダーバンドルを作成します。デプロイメント用にdistフォルダー内のすべてのファイルをアップロードできます。

ng build --prod --aot --base-href。


0

ng serveは、開発目的でアプリケーションを提供するために機能します。生産についてはどうですか?package.jsonファイルを調べると、使用できるスクリプトがあることがわかります。

"scripts": {
  "ng": "ng",
  "start": "ng serve",
  "build": "ng build --prod",
  "test": "ng test",
  "lint": "ng lint",
  "e2e": "ng e2e"
},

ビルドスクリプトは、-prodフラグを指定したAngular CLIのngビルドを使用します。今それを試してみましょう。次の2つの方法のいずれかで実行できます。

#npmスクリプトを使用する

npm run build

#CLIを直接使用する

ng build --prod

今回は5つではなく4つのファイルが与えられます。--prodフラグは、アプリケーションのサイズをはるかに小さくするようにAngularに指示します。

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