web-dev-qa-db-ja.com

バンドルする方法 Angular 生産用アプリ

このスレッドで、ライブWebサーバーでの運用のためにAngular(バージョン2、4、...)をバンドルするための最新の(そしてうまくいけば最も簡単な)方法を追跡し、更新したいと思います。

回答の中にAngularバージョンを含めるようにしてください。

315
Pat M

Angular CLIを使用した2.x, 4.x, 5.x, 6.x, 7.x, 8.x(TypeScript)

ワンタイムセットアップ

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

結束ステップ

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

    flag prod本番用バンドル(本番フラグに含まれるオプションのリストについては Angular documentation を参照してください)。

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

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

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

出力

Angular 8.0.0のサイズ8.0.1およびAngularルーティングなしのオプションCSS

  • dist/main-[es-version].[hash].jsバンドルされたアプリケーション[ES5サイズ:新しいAngular CLIアプリケーションの153 KB、空(37 KB圧縮)。
  • dist/polyfill-[es-version].[hash].bundle.jsバンドルされたポリフィル依存関係(@ angular、RxJS ...)[ES5サイズ:新しいAngular CLIアプリケーションの空の111 KB、33 KB圧縮]。
  • dist/index.htmlアプリケーションのエントリポイント。
  • dist/runtime-[es-version].[hash].bundle.js webpack loader
  • dist/style.[hash].bundle.cssスタイル定義
  • Angular CLIアセット構成からコピーされたdist/assetsリソース

展開

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

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

335

Gulpを使った2.0.1 Final(TypeScript - Target:ES5)


ワンタイムセットアップ

  • npm install(direcoryがprojectFolderの場合はcmdで実行されます)

バンドリング手順

  • npm run bundle(direcoryが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.js (ちょうどsystemjs.config.jsonとの違いを示しています)
var map = {
    'app':                        'dist/app',
  };
  • projectFolder/index.html (production) - スクリプトタグの順序は重要です。バンドルタグの後に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 は、ブートストラップの場所です。

私はまだできた最高の:)

53
Ankit Singh

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

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

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

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

指示

  • npm install

  • npm start。開発用です。これはあなたのlocalhostアドレスにlivereloadedされる仮想の "dist"フォルダを作成します。

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

2 - Webkitスターターキット

この Webpack Starter Kit は上記のチュートリアルよりもさらに多くのテスト機能を提供しており、非常に人気があります。

22
Pat M

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

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

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

  1. きれいなタイプスクリプトをコンパイルしたjsファイルとdistフォルダ
  2. アプリフォルダ内のTypeScriptファイルをコンパイルする
  3. SystemJsバンドラーを使用して、ブラウザのキャッシュを更新するために生成されたハッシュを持つdistフォルダにすべてをバンドルします。
  4. Gulp-html-replaceを使用してindex.htmlスクリプトをバンドル版に置き換え、distフォルダーにコピーします。
  5. Assetsフォルダー内のすべてのものをdistフォルダーにコピーします

Node :あなたはいつでもあなた自身のビルドプロセスを作成することができますが、それには必要なワークフローがすべて揃っていて完全に動作するのでAngular-Cliを使用することを強くお勧めします。私たちはすでにプロダクションでそれを使っていて、Angular-Cliについてはまったく問題がありません。

14

Angular CLI 1.x.x(Angular 4.x.x、5.x.xで機能します)

これはサポートします:

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

初期設定

 ng新しいプロジェクト名--routing 

SASSの.scssサポートのために--style=scssを追加することができます。

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

プロジェクトを作成した後、CLIは自動的にnpm installを実行します。もしあなたが代わりにYarnを使いたい、あるいは単にインストールせずにプロジェクトのスケルトンを見たいのなら、 ここでそれを行う方法をチェックしてください

バンドル手順

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

 ng build -prod 

現在のバージョンでは--aotを手動で指定する必要があります、なぜならそれは開発モードで使うことができるからです(遅いので実用的ではありませんが)。

これは、さらに小さいバンドルに対してもAoTコンパイルを実行します(Angularコンパイラなし、代わりに生成されたコンパイラ出力)。生成コードが小さいためAngular 4を使用すると、バンドルはAoTではるかに小さくなります。
ng build --aotを実行することで、開発モードのAoT(ソースマップ、縮小なし)および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
    CSSのWebpackローダーを使用すると(CLIの方法です)、ここではJS経由でロードされます。

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

その他のファイル

他の状況では、他の不要なファイル/フォルダが見つかる可能性があります。

  • ./out-tsc/
    ./src/tsconfig.jsonoutDirから
  • ./out-tsc-e2e/
    ./e2e/tsconfig.jsonoutDirから
  • ./dist/ngfactory/
    AoTコンパイラから(ベータ16の時点でCLIをフォークせずに構成することはできません)
13
Meligy

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

私のこれまでのAngular 2での経験は、AoTがほとんどロード時間なしで最小のビルドを作成するということです。そして、ここでの質問が最も重要である - あなたは本番に少数のファイルを出荷するだけでよいです。

これは、テンプレートが "Ahead of Time"でコンパイルされているため、Angularコンパイラがプロダクションビルドに同梱されないためです。 HTMLテンプレートのマークアップが、元のHTMLにリバースエンジニアリングするのが非常に難しいJavaScriptの命令に変換されているのも非常にクールです。

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

https://youtu.be/ZoZDCgQwnmQ

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

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

5
        **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="/">
    </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
Tushar Tibude

angular-cli-ghpages を使用してgithubにAngularアプリケーションをデプロイできます。

このcliを使用してデプロイする方法を見つけるためにリンクをチェックしてください。

デプロイされたWebサイトは通常githubのあるブランチに保存されます。

gHページ

useはgitブランチを複製し、あなたのサーバーの静的ウェブサイトのように使うことができます。

2
Sunil Kumar

「最高」はシナリオによって異なります。可能な限り小さい単一のバンドルを気にするだけの場合もありますが、大規模なアプリケーションでは遅延ロードを考慮する必要があるかもしれません。ある時点で、アプリ全体を1つのバンドルとして扱うことは実用的ではなくなります。

後者の場合、Webpackはコード分割をサポートしているので一般的に最善の方法です。

シングルバンドルの場合、Rollup、またはあなたが勇気を感じているならClosureコンパイラを検討するでしょう:-)

ここで使ったことがあるすべてのAngularバンドラーのサンプルを作成しました。 http://www.syntaxsuccess.com/viewarticle/angular-production-builds

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

アンギュラバージョン:4.1.x

1
TGH

1分以内にwebpack 3を使ってAngular 4をセットアップするだけで、問題なくENVバンドルの準備が整います。以下のgithubのドキュメントに従ってください。

https://github.com/roshan3133/angular2-webpack-starter

0
AniketGole

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

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

0
Nagnath Mungade