AngularJSとGruntで稼働環境によって接続先APIを切り替える
今年の夏は、家族旅行で行った海ではしゃぎ過ぎ、温泉宿に付いた瞬間に疲れ果ててしまい肝心の温泉にあまり浸かれず、翌日全身筋肉痛となって帰宅したのがハイライトだった.....代表の国本です。
Webサービスやスマホ・アプリ開発では実際にサービスが稼働する本番環境の他に、同等のステージングや開発環境をセットで構築することが多々あるかと思います。
現在弊社のプロジェクトではクライアントサイドのフレームワークとしてAngularJSを積極的に採用しており、今回はEnvironment Specific Configuration in AngularJS Using Grunt
を参考に、Gruntを使用してAngularJSでステージングや本番環境など、稼働環境に応じて接続するAPIを切り替える方法について書いてみようと思います。
事前準備
今回は、Yeomanを使い、本ブログエントリーのために専用のenviromentsAppというアプリを作成します。
% yo angular enviromentsApp --coffee
アプリのサービスで利用するAPIの接続先が開発環境、ステージング、本番それぞれで異なるという想定で以下手順を進めて行きたいと思います。
generator-env-configの導入
それぞれの環境で区分したいAPIのURLを設定ファイル化するための、Yeomanのジェネレーターであるgenerator-env-configをnpm経由でインストールします。
% npm install generator-env-config
インストールが完了後、下記コマンドを実行し、まずは開発環境用の設定ファイルを生成します。
% yo env-config
実行後、config/environments/development.json
が生成されます。
アプリ直下に生成されたconfig/enviroments
配下のJSONファイルで、実行環境毎の設定値を管理します。(Railsにおけるconfig/enviromentsのイメージですね)
同じように、ステージング用、本番用のJSONファイルも生成しておきましょう。
% yo env-config staging
% yo env-config production
% ll config/environments/
total 24
drwxr-xr-x 5 kuninori wheel 170 8 26 21:09 .
drwxr-xr-x 4 kuninori wheel 136 8 26 20:50 ..
-rw-r--r-- 1 kuninori wheel 40 8 26 20:50 development.json
-rw-r--r-- 1 kuninori wheel 19 8 26 21:09 production.json
-rw-r--r-- 1 kuninori wheel 19 8 26 21:09 staging.json
今回はAPIの接続URLを実行環境毎に区分する。という想定なのでconfig/environments/
配下のそれぞれの環境設定JSONファイルに下記設定を行います。
// development.json
{
"apiUrl": "http://localhost:9000"
}
// staging.json
{
"apiUrl": "http://staging.local"
}
// production.json
{
"apiUrl": "http://production.local"
}
AngularJSモジュールの生成
次に、env-configを使用してAngularJS上で実行環境毎の設定値を管理するservices.config
というモジュールを作成します。
先程JSONファイルに設定されたそれぞれの環境用の設定値は、このservices.config
モジュールをロードすることで利用できるようになります。
まず、下記コマンドを実行します。
% yo env-config:angular config
コマンド実行後、config/config.js
というファイルが生成されており、その中でservices.config
モジュールが定義されています。
services.config
モジュールで、JSON設定ファイル内に定義されているAPIのURL(apiUrl)を扱えるようにします。
'use strict';
angular.module('services.config', [])
.constant('configuration', {
// apiUrl変数を定義する
apiUrl: '@@apiUrl'
});
grunt-replaceの導入とタスクの定義
次にGruntを使用しそれぞれの環境用の設定値を動的に生成できるようにgrunt-replace
をnpmで導入し、ビルド用タスクを定義します。
まずはgrunt-replace
をインストール
% npm install grunt-replace --save-dev
インストール後、grunt-replace
をロードするようにGruntfile.js
の編集を行います。
module.exports = function (grunt) {
// module.exports内に下記設定を追記する
grunt.loadNpmTasks('grunt-replace');
併せてgrunt-replace
用のタスクをgrunt.initConfig
配下に定義します。
grunt.initConfig({
replace: {
development: {
options: {
patterns: [{
json: grunt.file.readJSON('./config/environments/development.json')
}]
},
files: [{
expand: true,
flatten: true,
src: ['./config/config.js'],
dest: '<%= yeoman.app %>/scripts/services/'
}]
},
staging: {
options: {
patterns: [{
json: grunt.file.readJSON('./config/environments/staging.json')
}]
},
files: [{
expand: true,
flatten: true,
src: ['./config/config.js'],
dest: '<%= yeoman.app %>/scripts/services/'
}]
},
production: {
options: {
patterns: [{
json: grunt.file.readJSON('./config/environments/production.json')
}]
},
files: [{
expand: true,
flatten: true,
src: ['./config/config.js'],
dest: '<%= yeoman.app %>/scripts/services/'
}]
}
}
タスクが定義できたら、早速開発環境用のタスクを走らせてみましょう
% grunt replace:development
Running "replace:development" (replace) task
Replace ./config/config.js → app/scripts/services/config.js
Done, without errors.
タスクが正常終了後、app/scripts/services/config.js
ファイルが生成されます。
config/environments/development.json
で定義した、開発環境向けのAPIのURLがモジュールとして定義されているのが確認できます。
'use strict';
angular.module('services.config', [])
.constant('configuration', {
apiUrl: 'http://localhost:9000'
});
AngularJSアプリでservices.configモジュールをロード
これまでの手順で、それぞれの稼働環境用の変数が定義されたservices.config
モジュールが生成できる環境が整ったため、生成されたservices.config
モジュールをAngularJSアプリケーションからロードし利用できるようにしましょう。
まずはapp/index.html
でservices.config
モジュール用のJavaScriptを読み込みます。
# config.jsをindex.htmlに追加
<script src="scripts/services/config.js"></script>
次に、app/scripts/app.coffee
からモジュールをロード。
'use strict'
###*
# @ngdoc overview
# @name enviromentsAppApp
# @description
# # enviromentsAppApp
#
# Main module of the application.
###
angular
.module('enviromentsAppApp', [
'ngAnimate',
'ngCookies',
'ngResource',
'ngRoute',
'ngSanitize',
'ngTouch',
// services.configをロードするように追加
'services.config'
])
これでモジュールが呼び出せるので、早速コントローラーから定義されているAPI用のURLを確認してみましょう。
'use strict'
###*
# @ngdoc function
# @name enviromentsAppApp.controller:MainCtrl
# @description
# # MainCtrl
# Controller of the enviromentsAppApp
###
angular.module('enviromentsAppApp')
// configurationをセット
.controller 'MainCtrl', ($scope, configuration) ->
// configuration.apiUrlで定義しているAPIのURLをアラート表示してみる
alert configuration.apiUrl
起動してみると......。
定義しているAPIのURLが表示されましたね。
後は、実際にS3やWebサーバへAngularJSアプリケーションをデプロイする際に実行するGruntのビルド処理の中で
grunt replace:staging
や grunt replace:production
を実行するように仕込めば、デプロイ環境に併せて
フレキシブルに環境変数が準備できます。
まとめ
いかがでしたでしょうか? 今回活用したgenerator-env-config
以外にも環境ごとの設定値を良い感じに定義する手法は数多くあるかと思いますので
ご教示いただければ幸いです。
ではでは、良きAngularJSライフを╭( ・ㅂ・)و ̑̑
今回ご紹介したような、AngularJSなどのフレームワークを活用したフロントエンドアプリケーション開発を御希望の企業様は、是非お気軽にMMMにご相談下さいませ!