この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
どうも!大阪オフィスの西村祐二です。
AngularではAngular CLIを使えば簡単にビルドすることができます。
ただ、デフォルトだと、
ng build
または、ng build --prod
で、2つの環境のみ切り替えができる状況です。
しかし、環境はdev、stg、prodと3つあることが多いと思います。
そこで、今回、dev、stg、prodの3つの環境で設定を切り替えてビルドできるようにしてみたいと思います。
環境
- Angular CLI: 6.1.5
- Node: 8.11.3
- OS: darwin x64
- Angular: 6.1.4
テストプロジェクト作成
cliでプロジェクトを作成します。
$ ng new test-build
stg環境の環境ファイル作成と設定
デフォルトで作成される環境ファイルのenvironment.prod.ts
をprod環境用、environment.ts
をdev環境用とします。
stg環境用のファイルは自分で作成します。
- environment.prod.ts
- prod環境
- environment.ts
- dev環境
- environment.stg.ts(作成)
- stg環境
$ cd ./test-build/src/environments
$ touch environment.stg.ts
build時に設定が切り替わっているか、わかりやすいようにファイルを下記のように編集しておきます。
environment.prod.ts
export const environment = {
production: true,
apiUrl : 'prod環境のurl'
};
environment.stg.ts
export const environment = {
production: false,
apiUrl: 'stg環境のurl'
};
environment.ts
export const environment = {
production: false,
apiUrl: 'dev環境のurl'
};
angular.jsonを編集
build時にstg環境の環境ファイルを読み込むように設定を追加します。おまけで、ng serve -c stg
でstg環境の設定を読み込んでサーバ起動するようにも設定しておきます。
angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"test-build": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/test-build",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"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,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
},
"stg": {
"fileReplacements": [{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.stg.ts"
}],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "test-build:build"
},
"configurations": {
"production": {
"browserTarget": "test-build:build:production"
},
"stg": {
"browserTarget": "test-build:build:stg"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "test-build:build"
}
},
.
.
.
CSSのテーマも切り替えるようにする
よくAngular Materialを使うのですが、環境ごとにテーマを切り替えて環境の視認性を上げたいということがよくあります。
fileReplacements
を使ってファイルを差し替える方法はこちらのISSUEよりSCSSは動作しないようです。
そこで回避策として、ISSUEにも書かれているとおりstylePreprocessorOptions
を設定してSCSSのパス設定で切り替えるようにしてみます。
まずは、環境ごとにテーマファイルを作成します。中身は
@import '@angular/material/prebuilt-themes/deeppurple-amber.css';
など、それぞれ違うテーマや設定をしておきます。
また、ポイントとしては環境ごとにフォルダ分けするところと、テーマファイルのファイル名を揃えおきます。
環境ごとにthemeのファイルを作成しておきます
src/theme/local/theme.scss
src/theme/prod/theme.scss
src/theme/stg/theme.scss
styles.scssには下記のようにテーマを参照するように設定します。
src/styles.scss
@import 'theme';
angular.jsonで環境ごとにパスを設定します。
angular.json
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"test-build": {
"root": "",
"sourceRoot": "src",
"projectType": "application",
"prefix": "app",
"schematics": {},
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/test-build",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"stylePreprocessorOptions": {
"includePaths": ["src/theme/local/"]
},
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"stylePreprocessorOptions": {
"includePaths": ["src/theme/prod/"]
},
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
},
"stg": {
"stylePreprocessorOptions": {
"includePaths": ["src/theme/stg/"]
},
"fileReplacements": [{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.stg.ts"
}],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "test-build:build"
},
"configurations": {
"production": {
"browserTarget": "test-build:build:production"
},
"stg": {
"browserTarget": "test-build:build:stg"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "test-build:build"
}
},
.
.
.
これで、styles.scssではそれぞれの環境のtheme.scssを読み込んでくれます。
動作確認
環境ファイルに書き込んだapiUrl
を表示するように設定します。
src/app/app.component.html
{{env}}
src/app/app.component.ts
import { environment } from './../environments/environment';
import { Component, enableProdMode } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'test-build';
env = environment.apiUrl;
}
▼dev環境用の環境ファイルを読み込んでビルドしてみる。
$ ng build
ビルドされたファイルの確認はhttp-serve
をつかえば簡単に確認できます。
$ cd dist/test-build
$ http-serve
ブラウザから
http://0.0.0.0:8000/
にアクセス
▼同様にstg環境用の環境ファイルを読み込んでビルドしてみる。
$ ng build -c stg
▼同様にprod環境用の環境ファイルを読み込んでビルドしてみる。
$ ng build --prod
さいごに
いかがだったでしょうか。
ngコマンドでdev、stg、prodの3つの環境設定に切り替えてビルドできるようにしてみました。これで環境ごとの自動デプロイの仕組みなど簡単に作れますね。
誰かの参考になれば幸いです。