2017.5.29
2017.6.19

開発(development)と本番(production)の設定ファイルを切り替える

Visual Studio 2017のIonic2テンプレートで作成したプロジェクトに対して、開発(development)と本番(production)の設定ファイルを切り替える方法についてです。

以前、Angular2ベースのWebサイトを構築した際にWebpackを利用して設定ファイルを切り替えたことがあったので(webpackで開発と本番用の設定ファイルを切り替える)、今回も同じような感じでやれば問題ないと思っていましたが、テンプレート用のプロジェクトが自動生成された時点でWebpackやpackage.json、Visual Studio独自の設定などがあって気軽に変更することが難しく、結果としてはかなり違った形での実装となりました。

初めに断っておくと、DebugとReleaseビルドで設定ファイルを自動で切り替えられる方法を探しましたが見つからなかったので、切り替える際には一箇所「package.json」の値を変更する必要があります。

もしかしたら他に方法があるかもしれませんので、参考程度でお願いします。

目次

  • ディレクトリ、ファイルの構成
  • webpack.config.js
  • dev.json、prod.json
  • declarations.d.ts
  • environment.ts
  • app.module.ts
  • app.component.ts
  • package.json
  • 参考リンク

ディレクトリ、ファイルの構成

設定ファイルの切替に関連するもののみ記載しています。

project
├ package.json
├ config
│  └ webpack.config.js
├ environment
│  ├ dev.json
│  └ prod.json
└ src
    ├ declarations.d.ts
    └ app
        ├ environment.ts
        ├ app.module.ts
        └ app.component.ts

webpack.config.js

まず、プロジェクト直下に「config」フォルダを作成して、その下に「webpack.config.js」を作成します。

ファイルの内容は以下の通りです。


// Set the `ENV` global variable to be used in the app.
var path = require('path');
var webpack = require('webpack');

var projectRootDir = process.env.IONIC_ROOT_DIR;
var appScriptsDir = process.env.IONIC_APP_SCRIPTS_DIR;

// appScriptsDir > ...\node_modules\@ionic\app-scripts
var config = require(path.join(appScriptsDir, 'config', 'webpack.config.js'));

var env = process.env.IONIC_ENV || 'dev';
var envVars = require(path.join(projectRootDir, 'environment', env + '.json'));

config.plugins = config.plugins || [];
config.plugins.push(
    new webpack.DefinePlugin({
      'ENV': JSON.stringify(env),
      'SERVICE_URL': JSON.stringify(envVars.SERVICE_URL),
    })
);

if (env === 'prod') {
    // This helps ensure the builds are consistent if source hasn't changed:
    config.plugins.push(new webpack.optimize.OccurrenceOrderPlugin());
}

module.exports = config;

上記でやっていることは、ビルド実行時に呼び出されるWebpackの設定ファイル「...\node_modules\@ionic\app-scripts\config\webpack.config.js」をベースに、こちらで用意した開発と本番の設定用JSONファイル(environment\dev.json、environment\prod.json)を読み込んで、グローバルの変数(ENV、SERVICE_URL)として値をセットしています。

「process.env.IONIC_ENV」には「dev」または「prod」のどちらかがセットされています。

「webpack.optimize.OccurrenceOrderPlugin()」は、JS圧縮時にモジュールの利用頻度を考慮して並び替えてくれるようです。

dev.json、prod.json

プロジェクト直下に「environment」フォルダを作成して、開発と本番で切り替えたい情報をJSONファイルで用意します。

dev.json


{
  "SERVICE_URL": "http://localhost/"
}

prod.json


{
  "SERVICE_URL": "http://example.com/"
}

declarations.d.ts

「declarations.d.ts」ファイルはIonic2のテンプレートを利用してプロジェクトを作成した場合、デフォルトで用意されていると思います。

ファイルの一番下に以下の内容を追記します。


declare const ENV;
declare const SERVICE_URL;

Webpackで設定したグローバル変数をアプリケーションで利用する際には、ここで変数の宣言が必要です。宣言されていない場合、TypeScriptのコンパイルで以下のようなエラーが発生します。

Cannot find name 'SERVICE_URL'.

environment.ts

フォルダ「src\app」直下に「environment.ts」ファイルを作成します。

ファイルの内容は以下の通りです。


import { enableProdMode } from '@angular/core';

let PROVIDERS: any[] = [
  // common env directives
];

if ('prod' === ENV) {
  enableProdMode();

  PROVIDERS = [
    ...PROVIDERS,
    // custom providers in production
  ];
} else {

  PROVIDERS = [
    ...PROVIDERS,
    // custom providers in development
  ];
}

export const ENV_PROVIDERS = [
  ...PROVIDERS
];

このファイルはこちらの記事(webpackで開発と本番用の設定ファイルを切り替える)で作成したものとほとんど同じものになります。

このファイルで一番やりたいことは、アプリケーション起動時に「production」モードだったなら「enableProdMode()」メソッドを実行することです。

Angular2では「enableProdMode()」が実行されていない場合、コンソールに以下のようなログが出力されます。

Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.

「enableProdMode()」で開発モードをOFFにすると、フレームワークで行っているチェック処理などが無効になります。

「PROVIDERS」には、開発と本番で切り替えたいものがあれば追加します。なければそのままでOKです。

app.module.ts

上記の「environment.ts」をアプリケーションに組み込みます。(必要なもの以外は省略しています。)


import { ENV_PROVIDERS } from './environment';

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    ...
  ],
  providers: [
    ...
    ENV_PROVIDERS
  ]
})

app.component.ts

追加したグローバル変数を各コンポーネントで以下のように利用します。


@Component({
  ...
})
export class MyApp {
  ...
  constructor(public platform: Platform) {
    this.initializeApp();
    ...
  }

  initializeApp() {
    console.log(ENV);
    console.log(SERVICE_URL);
  }
}

package.json

最後に「package.json」の設定になります。

まず、ファイルに「ionic:build:prod」を追加します。


{
  ...
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "ionic:build": "ionic-app-scripts build",
    "ionic:build:prod": "ionic-app-scripts build --prod",
    "ionic:serve": "ionic-app-scripts serve",
    "watch": "ionic-app-scripts watch"
  },
  ...
}

上記の設定だけではDebugビルドだろうがReleaseビルドだろうが、追加された「ionic:build:prod」は実行されません。ビルド時に実行するためには同じ「package.json」ファイルの「-vs-binding > BeforeBuild」の値を切り替えてやる必要があります。

デフォルトでは以下のようになっているので、


{
  ...
  "-vs-binding": {
    "BeforeBuild": [
      "ionic:build"
    ]
  },
  ...
}

本番モードで実行したい時は以下のように修正します。


{
  ...
  "-vs-binding": {
    "BeforeBuild": [
      "ionic:build:prod"
    ]
  },
  ...
}

以上の設定で、開発(development)と本番(production)モードを切り替える際には、BeforeBuildの情報を変更することで可能になります。

本当は「Debug」ビルドと「Release」ビルドで読み込まれる設定ファイルを”自動”で切り替えたかったのですが、すいません、方法が分かりませんでした。

参考リンク

Ionic】関連記事