實務上會有不同 Angular 執行環境,如開發用的 dev
環境,測試用的 lab
與 stg
環境,正式上線用的 prod
環境,不同的環境會有不同的 環境變數
,如 API server 、S3 server 的設定 … 等,Angular CLI 提供了很方便的機制處理環境變數問題,讓我們切換不同環境時,完全不用改 code,只要在 Angular CLI 編譯時使用不同的參數切換即可。
Version
Node.js 8.9.3
Angular CLI 1.6.2
Angular 5.2
Angular CLI 預設 Environments
一個乾淨的 Angular 專案,已經提供了預設的 environment 設定。
- 選擇專案根目錄的
.angular-cli.json
- 在
environments
property 下,已經有dev
與prod
兩個設定,分別對應到environments
目錄下的environment.ts
與environment.prod.ts
-
environment.prod.ts
為prod
環境所使用的設定檔;而environment.ts
為dev
環境所使用的設定檔 -
以
environment.prod.ts
為例,設定了production: true
;而environment.ts
則設定了production: false
Q : production
property 設定為 true
或 false
有什麼影響 ?
- production: true : JavaScript 與 CSS 都會壓縮,且不提供 source map,因此最後的 JavaScript 與 CSS 會較小,適合
stg
與prod
環境使用,但不利於 debug - production: false : JavaScript 與 CSS 不會壓縮,會提供 source map,因此最後的 JavaScript 與 CSS 會較大,適合
dev
與lab
環境使用,方便 debug
新增 Lab 與 Stage 環境設定
Angular CLI 預設只提供了 dev
與 prod
兩個環境變數,但實務上最少還有 lab
與 stage
兩個環境,這必須手動建立。
Lab 環境
- 在
src/app/environments
目錄下新增environment.lab.ts
- 將
environment.ts
內容複製到environment.lab.ts
目前 Angular CLI 尚未提供指令建立 environment,必須手動建立,Angular CLI 的 naming convention 是 environment.
+ 環境名稱
+ .ts
environment.lab.ts
expot const environment = { production: false, envName: 'lab', };
- production: false :
lab
環境不提供 JavaScript 壓縮與最佳化,方便 debug - envName:
lab
: 可自行設定自己的變數
Stage 環境
- 在
src/app/environments
目錄下新增environment.stg.ts
- 將
environment.prod.ts
內容複製到environment.stg.ts
environment.stg.ts
export const environment = { production: true, envName: 'stg' };
- production: true :
stg
環境提供 JavaScript 壓縮與最佳化,與prod
環境相同 - envName:
stg
: 可自行設定自己的變數
為了測試方便,請在 environment.ts
加上 envName: 'dev'
, environment.prod.ts
加上 envName: 'prod'
修改 .angular-cli.json
- 選擇專案根目錄的
.angular-cli.jsonv
- 新增
lab
與stg
設定
.angular-cli.json
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "project": { "name": "ng52-environment" }, "apps": [ { "root": "src", "outDir": "dist", "assets": [ "assets", "favicon.ico" ], "index": "index.html", "main": "main.ts", "polyfills": "polyfills.ts", "test": "test.ts", "tsconfig": "tsconfig.app.json", "testTsconfig": "tsconfig.spec.json", "prefix": "app", "styles": [ "styles.css" ], "scripts": [], "environmentSource": "environments/environment.ts", "environments": { "dev": "environments/environment.ts", "lab": "environments/environment.lab.ts", "stg": "environments/environment.stg.ts", "prod": "environments/environment.prod.ts" } } ], "e2e": { "protractor": { "config": "./protractor.conf.js" } }, "lint": [ { "project": "src/tsconfig.app.json", "exclude": "**/node_modules/**" }, { "project": "src/tsconfig.spec.json", "exclude": "**/node_modules/**" }, { "project": "e2e/tsconfig.e2e.json", "exclude": "**/node_modules/**" } ], "test": { "karma": { "config": "./karma.conf.js" } }, "defaults": { "styleExt": "css", "component": {} } }
26 行
"environments": { "dev": "environments/environment.ts", "lab": "environments/environment.lab.ts", "stg": "environments/environment.stg.ts", "prod": "environments/environment.prod.ts" }
新增 lab
與 stg
,與其對應的 environments/environment.lab.ts
與 environments/environment.stg.ts
。
使用環境變數
app.component.html
<!--The content below is only a placeholder and can be replaced.--> <div > <h1> Welcome to {{ title }}! </h1> <h1> {{ environmentName }} </h1> <img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="> </div> <h2>Here are some links to help you start: </h2> <ul> <li> <h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2> </li> <li> <h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2> </li> <li> <h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2> </li> </ul>
第 6 行
<h1> {{ environmentName }} </h1>
在 Angular 專案預設的 app.component.html
加上 ,用來讀取
環境變數
。
app.component.ts
import { Component } from '@angular/core'; import { environment } from '../environments/environment'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; environmentName = environment.envName; }
11 行
environmentName = environment.envName;
直接讀取剛剛 export 的 environment.envName
。
切換環境變數
理想上,無論我們怎麼切換環境,都不應該去改 code,這才符合 開放封閉原則
的要求。
package.json
{ "name": "ng52-environment", "version": "0.0.0", "license": "MIT", "scripts": { "ng": "ng", "start": "ng serve", "start-lab": "ng serve --environment=lab", "start-stg": "ng serve --environment=stg", "start-prod": "ng serve --environment=prod", "build": "ng build --prod", "build-stg": "ng build --environment=stg", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" }, "private": true, "dependencies": { "@angular/animations": "^5.0.0", "@angular/common": "^5.0.0", "@angular/compiler": "^5.0.0", "@angular/core": "^5.0.0", "@angular/forms": "^5.0.0", "@angular/http": "^5.0.0", "@angular/platform-browser": "^5.0.0", "@angular/platform-browser-dynamic": "^5.0.0", "@angular/router": "^5.0.0", "core-js": "^2.4.1", "rxjs": "^5.5.2", "zone.js": "^0.8.14" }, "devDependencies": { "@angular/cli": "1.6.2", "@angular/compiler-cli": "^5.0.0", "@angular/language-service": "^5.0.0", "@types/jasmine": "~2.5.53", "@types/jasminewd2": "~2.0.2", "@types/node": "~6.0.60", "codelyzer": "^4.0.1", "jasmine-core": "~2.6.2", "jasmine-spec-reporter": "~4.1.0", "karma": "~1.7.0", "karma-chrome-launcher": "~2.1.1", "karma-cli": "~1.0.1", "karma-coverage-istanbul-reporter": "^1.2.1", "karma-jasmine": "~1.1.0", "karma-jasmine-html-reporter": "^0.2.2", "protractor": "~5.1.2", "ts-node": "~3.2.0", "tslint": "~5.7.0", "typescript": "~2.4.2" } }
第 5 行
"scripts": { "ng": "ng", "start": "ng serve", "start-lab": "ng serve --environment=lab", "start-stg": "ng serve --environment=stg", "start-prod": "ng serve --environment=prod", "build": "ng build --prod", "build-stg": "ng build --prod --environment=stg", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e" },
原本的 scripts
加上 start-lab
、 start-stg
、 start-prod
與 build-stg
。
第 7 行
"start": "ng serve",
Angular CLI 原本內建的 start
,不加任何參數,預設就是跑 dev
環境變數。
第 8 行
"start-lab": "ng serve --environment=lab",
新增 starrt-lab
, ng serve
時執行 lab
環境變數。
第 9 行
"start-stg": "ng serve --environment=stg",
新增 starrt-stg
, ng serve
時執行 stg
環境變數。
10 行
"start-prod": "ng serve --environment=prod",
新增 starrt-prod
, ng serve
時執行 prod
環境變數。
11 行
"build": "ng build --prod",
Angular CLI 原本內建的 build
,不加任何參數,預設就是跑 prod
環境變數。
12 行
"build-stg": "ng build --prod --environment=stg",
新增 build-stg
, ng build
除了如同 prod
編譯 JavaScript 外,同時跑 stg
環境變數。
以 Angular CLI 執行
執行 ng serve
時,跑的是 Angular CLI 內建的 web server。
使用 dev
執行
~/MyProject $ npm run start
在專案目錄下執行 npm run start
。
Angular 首頁顯示 dev
環境。
使用 lab
執行
~/MyProject $ npm run start-lab
在專案目錄下執行 npm run start-lab
。
Angular 首頁顯示 lab
環境。
使用 stg
執行
~/MyProject $ npm run start-stg
在專案目錄下執行 npm run start-stg
。
Angular 首頁顯示 stg
環境。
使用 prod
執行
~/MyProject$ npm run start-prod
在專案目錄下執行 npm run start-prod
。
Angular 首頁顯示 prod
環境。
以實際 Web Server 執行
Angular CLI 雖然內建 web server,但你或許覺得要實際跑過 ng build
的結果,較接近 stg
與 prod
環境。
安裝 http-server
$ npm install -g http-server
另外安裝 http-server
執行 ng build
結果,不透過 Angular CLI。
- -g : 安裝
http-server
在 global
使用 stg
編譯
~/MyProject $ npm run build-stg
在專案目錄下執行 npm run build-stg。
~/MyProject/dist $ http-server
ng build
會將編譯後的檔案放到 dist
目錄下,在 dist
目錄下執行 http-server
。
http-server
會啟動在 http://172.20.10.12:8080
。
Angular 首頁顯示 stg
環境。
使用 prod
編譯
~/MyProject $ npm run build
在專案目錄下執行 npm run build。
ng build
會將編譯後的檔案放到 dist
目錄下,在 dist
目錄下執行 http-server
。
http-server
會啟動在 http://172.20.10.12:8080
。
Angular 首頁顯示 prod
環境。
Conclusion
- Angular CLI 已經幫我們設計好完整的
環境變數
機制,只要配合 Angular CLI 的架構,可以在完全不用修改任何一行 code 的狀態下,透過指令切換環境變數
Sample Code
完整的範例可以在我的 GitHub 上找到
Reference
Shayne Boyer , Angular 2: Application Settings using the CLI Environment Option
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。