LoginSignup
2

More than 3 years have passed since last update.

AnglarのビルドとFirebaseのデプロイを連動させる

Last updated at Posted at 2020-08-08

この記事はAngular+Firebaseでチャットアプリを作るのエントリーです。
前記事:WEBアプリでFirebaseのデプロイ環境を構築する

この記事で行うこと

前回の記事ではFirebaseのステージング運用とデプロイ方法について書きましたが、今回の記事ではAngularとFirebaseのデプロイを連動させる方法について書いていきます。

Angularのデプロイ

Angularに限らず、近年のJavaScriptアプリケーションでは開発環境と本番環境のビルドファイルを分けて作成することが多いです。開発環境ではデバッグをする必要があるため、SourceMapの表示を許容し、デバッグのしやすさを重視します。一方、本番環境ではファイルの読み込み速度や機密性が重視されるため、ファイルをminifyし、余計な情報を減らす作業が必要になります。

このビルド作業の使い分けは自力でやろうとすると面倒が多いため、webpackやgulpといったタスクランナーを使って管理することがデファクトスタンダードになっています。
Angularでも例に漏れず、裏側ではwebpackを使ってタスク処理をしているようですが、webpack.config.jsではなく、angular.jsonにビルド方式やテストツールの設定情報を記載しています。
「自前のwebpackでやりたい!」という方向けの@angular-builders/custom-webpackというものもあるので、自分で設定を書きたい方は以下のリンクを参考にしてください。

参考:Angular + カスタマイズWebpack 開発環境構築

実装内容

AngularとFirebaseを連動させてデプロイを行う場合は、AngularFireのng deployを使用します。このコマンドにより、開発環境に応じたビルド、デプロイを実現できるようになります。
AngularFireについては既に以前の記事でインストール方法等について紹介していますので、この記事から参照された方はそちらを確認してください。

参考:https://angular.io/guide/deployment

注1)ng deploy@angular/cliに導入されたのはv8.3.0以降となります。それ以前の@angular/cliを利用している場合は使用できませんのでご注意ください。
注2)@angular/cling deployは2020年の5月にバグが報告され、修正されています。下記の実装はそれ以前の@angular/cliだとエラーがでますので、最新の状態にしてください。
参考:https://github.com/angular/angular-cli/issues/17613

なお、今回使用するFirebaseのプロジェクトは2つで、次の様に設定します。

環境 Project ビルド方式
開発環境 開発用 開発用
ステージング環境 開発用 本番用
本番環境 本番用 本番用

開発環境にデプロイする

まず、angular.jsonのソースコードを確認します。

angular.json
"deploy": {
 "builder": "@angular/fire:deploy",
 "options": {},
}

@angular/cliv8.3.0以降のangular.jsonであれば、最初からng deployのための設定が記載されています。とりあえずこの状態でng deployを実行すると、ng build --prodコマンドを打った時と同じ挙動をします。

ただ、開発環境ではデバッグをする必要があるため、--prodをしないように設定する必要があります。

angular.json
"deploy": {
 "builder": "@angular/fire:deploy",
 "options": {
     "buildTarget": "NgChat:build",
 },
}

これで開発環境の設定は完了です。
ng deployをして、開発環境の挙動を確認します。

実行結果

デプロイ後の画面(ソースマップが確認できる)
スクリーンショット 2020-08-08 23.17.59.png

ステージング環境にデプロイする

まず、staging環境用の環境設定ファイルを作成します。
開発環境のsrc/environments/environment.tsをコピーし、productionをtrueにします。

src/environments/environment.staging.ts
export const environment = {
  production: true,
  firebase: {
    apiKey: '<your-key>',
    authDomain: '<your-project-authdomain>',
    databaseURL: '<your-database-URL>',
    projectId: '<your-project-id>',
    storageBucket: '<your-storage-bucket>',
    messagingSenderId: '<your-messaging-sender-id>',
    appId: '<your-app-id>',
    measurementId: '<your-measurement-id>',
  },
};

次にangular.jsonでビルド情報を設定します。buildオブジェクトにあるconfigurationsを見ると、すでにproduction用の設定は記載されているので、この内容をstaging用に修正します。
*設定ファイルパス以外は変更していません。

angular.json
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.staging.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "10kb"
                }
              ]
            }
          }

ここに書いてある設定情報が何を意味しているのかをざっくりまとめると、以下のようになります。

項目名 説明
fileReplacements ファイル差し替え。主にenvironmentファイルに使われる。
optimization 最適化する。{scripts: true, styles: false} というような個別設定も可能
outputHashing 出力ファイル名にハッシュをつける。キャッシュバスター。"none","all","media","bundles"
sourceMap sourceMapを出力する。{scripts: true, styles: true, hidden: false, vendor: true}というような個別設定も可能
extractCss グローバル指定のcssを展開する
namedChunks 遅延読み込みのファイルに名前をつける
extractLicenses 利用ライブラリのライセンスファイルをまとめる
vendorChunk ライブラリだけで単独のファイルにする。ライブラリは変更頻度が低いため。
buildOptimizer aot利用時、@angular-devkit/build-optimizerを有効にする
budgets 生成ファイルのファイルサイズ制限を設定できる。気軽に巨大なライブラリをimportすると使わないコードが大量に含まれてしまったりするのを警告する。

この内容は以下記事からの抜粋です。他のパラメータについてはそちらを参照してみてください。
参考:angular.jsonの中身

ここで指定した内容をもとにデプロイできるよう、angular.jsonのデプロイ情報に追記します。

angular.json
        "deploy": {
          "builder": "@angular/fire:deploy",
          "options": {
            "buildTarget": "NgChat:build"
          },
          "configurations": {
            "staging": {
              "buildTarget": "NgChat:build:production"
            }
          }
        }

これで準備が整いました。
あとは-cオプション(--configurationのエイリアス)をつけてデプロイします。

ng deploy -c staging

実行結果

デプロイ後の画面(ソースマップが確認できず、エラーは表示される)
スクリーンショット 2020-08-08 23.50.35.png

本番環境にデプロイする

最後に本番環境のデプロイ設定します。
Angularのプロジェクトにあるenvironment.prod.tsファイルにfirebaseの情報を追記します。この際、本番用プロジェクトのパラメータを使用してください。

src/environments/environment.prod.ts
export const environment = {
  production: true,
  firebase: {
    apiKey: '<your-key>',
    authDomain: '<your-project-authdomain>',
    databaseURL: '<your-database-URL>',
    projectId: '<your-project-id>',
    storageBucket: '<your-storage-bucket>',
    messagingSenderId: '<your-messaging-sender-id>',
    appId: '<your-app-id>',
    measurementId: '<your-measurement-id>',
  },
};

次にangular.jsonに本番用プロジェクトの追加をします。
servetestは開発・ステージング環境でのみ使用するため、本番用のプロジェクトからは除外しています。

angular.json
    "NgChatProd": {
      "projectType": "application",
      "schematics": {},
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/NgChat",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "aot": true,
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "src/styles.css"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "10kb"
                }
              ]
            }
          }
        },
        "deploy": {
          "builder": "@angular/fire:deploy",
          "options": {}
        }
      }
    }

この設定だけだどhostingデプロイ時にエラーがでるため、Firebase側の設定ファイルにも追記をします。
今回、ステージング用のFirebaseプロジェクトは使用しないため、開発用と本番用の2プロジェクトを作成します。

.firebaserc
{
  "projects": {
    "dev": "開発用FirebaseプロジェクトID",
    "prod": "本番用FirebaseプロジェクトID"
  },
  "targets": {
    "開発用FirebaseプロジェクトID": {
      "hosting": {
        "NgChat": [
          "開発用FirebaseプロジェクトID"
        ]
      }
    },
    "本番用FirebaseプロジェクトID": {
      "hosting": {
        "NgChatProd": [
          "本番用FirebaseプロジェクトID"
        ]
      }
    }
  }
}
firebase.json
    {
      "target": "NgChat",
      "public": "dist/NgChat",
      "ignore": [
        "firebase.json",
        "**/.*",
        "**/node_modules/**"
      ],
      "rewrites": [
        {
          "source": "**",
          "destination": "/index.html"
        }
      ]
    },
    {
      "target": "NgChatProd",
      "public": "dist/NgChat",
      "ignore": [
        "firebase.json",
        "**/.*",
        "**/node_modules/**"
      ],
      "rewrites": [
        {
          "source": "**",
          "destination": "/index.html"
        }
      ]
    }

これで本番環境の設定は完了です。ng deployの後にプロジェクト名をいれて実行します。

ng deploy NgChatProd

実行結果

デプロイ後の画面(ソースマップが確認できず、エラーは表示される)
スクリーンショット 2020-08-08 23.54.05.png

本記事をもって「Angular+Firebaseでチャットアプリを作る」のエントリーはすべて終了です。
お疲れ様でした。

ソースコード

この時点でのソースコード
※apiKeyは削除しているので、試すときは自身で作成したapiKeyを入れてください。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2