webpackで開発と本番用の設定ファイルを切り替える
Angular2のQuickStart環境をそのまま実行すると、以下のようなログがブラウザのコンソールに吐き出されます。
Angular is running in the development mode. Call enableProdMode() to enable the production mode.
ログの内容は、開発モードで実行されているので、本番用に実行するならenableProdMode()メソッドを呼んでね、という感じです。切り替えることでなにが変わるのかは分からないのですが、開発と本番で呼び出すサービスのURLを変えたかったこともあり、webpackの設定ファイルを利用してenableProdMode()メソッドを呼び出すとともに、サービスのURLを開発と本番モードを切り替えるようにしました。
やることは以下の通り。
- webpack-mergeのインストール
- 設定ファイルの作成(webpack.common.js、webpack.dev.js、webpack.prod.js)
- 設定ファイルを切り替える(package.json)
- モジュール側の環境設定用ファイルの作成(environment.ts)
- TypeScript用の型定義ファイル(.d.ts)の作成
- ENV(開発、本番モード)の利用
環境は、Angular2のQuickStartをベースにして、こちら(AngularClass/angular2-webpack-starter)を参考...というか、必要そうなところを抜き出したものになります。
以下、設定方法です。
目次
- webpack-mergeのインストール
- ディレクトリ構成とファイルの格納場所
- 設定ファイルの作成
- 設定ファイルを切り替える
- モジュール側の環境設定用ファイルの作成
- TypeScript用の型定義ファイル(.d.ts)の作成
- ENV(開発、本番モード)の利用
webpack-mergeのインストール
まず、webpackの設定ファイル切替用に「webpack-merge」をインストールします。
npm install webpack-merge --save-dev
ディレクトリ構成とファイルの格納場所
以下、今回関係あるファイルの格納場所です。
project ├ package.json ├ config │ ├ webpack.common.js │ ├ webpack.dev.js │ └ webpack.prod.js ├ dist │ ├ bundle.js │ └ index.html ├ node_modules └ src ├ custom-typings.d.ts ├ entry.js └ app ├ app.module.ts ├ app.service.ts └ environment.ts
設定ファイルの作成
続いて、トップにconfigフォルダを作成して、その下に、共通、開発用、本番用のwebpack設定ファイルを作成します。
webpack.common.js(共通)
module.exports = function () {
return {
entry: './src/entry.js',
output: {
path: './dist',
publicPath: '/',
filename: 'bundle.js'
},
module: {
rules: [
...
],
loaders: [
...
],
},
resolve: {
extensions: ['.js', '.css']
},
};
}
webpack.dev.js(開発用)
const commonConfig = require('./webpack.common.js'); // the settings that are common to prod and dev
const webpackMerge = require('webpack-merge'); // used to merge webpack configs
const DefinePlugin = require('webpack/lib/DefinePlugin');
const ENV = 'development';
module.exports = webpackMerge(commonConfig(), {
plugins: [
new DefinePlugin({
'ENV': JSON.stringify(ENV),
}),
]
});
webpack.prod.js(本番用)
const commonConfig = require('./webpack.common.js'); // the settings that are common to prod and dev
const webpackMerge = require('webpack-merge'); // used to merge webpack configs
const DefinePlugin = require('webpack/lib/DefinePlugin');
const ENV = 'production';
module.exports = webpackMerge(commonConfig(), {
plugins: [
new DefinePlugin({
'ENV': JSON.stringify(ENV),
}),
]
});
webpackの設定ファイルから「DefinePlugin」というプラグインを使うことで、設定値等の値をモジュールで参照できるようになります。
詳しくはこちら(Webpackを使ってJSでも.envしたい)を参照。
設定ファイルを切り替える
webpack設定ファイルの切替は「package.json」の「scripts」で行うので、開発、本番それぞれのwebpack設定ファイルを読み込むscriptsを用意します。
{
...
"scripts": {
"webpack:prod": "webpack --config config/webpack.prod.js",
"webpack:dev": "webpack --config config/webpack.dev.js",
},
...
}
モジュール側の環境設定用ファイルの作成
モジュール側でenableProdMode()メソッドを呼び出すためのファイルを用意します。
environment.ts(appフォルダ直下に作成)
import { enableProdMode } from '@angular/core';
let PROVIDERS: any[] = [
];
if ('production' === ENV) {
enableProdMode();
PROVIDERS = [
...PROVIDERS,
];
} else {
PROVIDERS = [
...PROVIDERS,
];
}
export const ENV_PROVIDERS = [
...PROVIDERS
];
上記で作成したファイルを「app.module.ts」で呼び出します。
import { ENV_PROVIDERS } from './environment';
@NgModule({
...
providers: [
ENV_PROVIDERS
],
...
})
export class AppModule {
}
TypeScript用の型定義ファイル(.d.ts)の作成
上記の対応だけではコンパイルエラー「Cannot find name 'ENV'.」が発生してしまいます。何が必要なのか探していたら、どうやら型定義のファイル「~~~.d.ts」が必要みたいでした。
「custom-typings.d.ts」ファイルをsrcフォルダ直下に作成して、内容は以下のようにします。(拡張子さえ「.d.ts」ならファイル名はなんでもいいみたいです)
declare var ENV: string;
型定義ファイルについて詳しくはこちら(Visual StudioとTypeScriptでJavaScriptライブラリを活用する)を参照してください。拡張子を見てわかる通り、TypeScript独自のファイルです。
ENV(開発、本番モード)の利用
以上で変数「ENV」に開発(development)、本番(production)モードの情報が格納されるようになるので、以下のように利用します。
export class AppService {
private serviceUrl = "";
constructor() {
if('production' === ENV){
this.serviceUrl = "/example";
}else{
this.serviceUrl = "http://localhost/example";
}
}
}
最初はなにやっているかさっぱりなAngular2のスターターキットでしたが、ちゃんと見ていけば、なんとなくですが分かるかるものなんですね。