[React] 依建置環境切分 create-react-app 產出專案的組態

如何在 create-react-app 產出專案中依據建置環境來切分各自的組態參數

前言


建立一個 react 專案最簡單的方式就是透過 create-react-app 這個官方 cli 來產出,雖然不如其他框架有多種 options 幫你準備齊全,但也只能忍耐了;當我們需要對 webpack 作進一步的設定時,可以透過 eject 指令產生所有設定檔 (這行為是不可逆的,請警慎使用),本文就是介紹要如何在此專案預設結構中切分出不同建置環境所需的組態資訊。

 

 

環境


create-react-app: 3.0.1
webpack: 4.29.6

 

 

傳入參數


首先必須知道需求是什麼,所以簡單列下兩點:

1. 建置時可以依不同"建置環境"設定 public path (若佈署在 sub directory 就必須設置)

2. 建置時可以依不同"建置環境"使用不同的常數設定 (ex. 每個環境對應後端的 api url 都不同)

 

因此在 build 時需要傳入以下兩項參數資訊:

1. Mode: 不同佈署環境的辨識資訊 (uat, sit, prod..)

2. RootPath: 佈署位置的 sub directory 資訊 (用來設定 webpack public path)

 

於 package.json 預定 script 語法,在呼叫 build.js 時傳入 mode 與 rootPath 資訊。

"scripts": {

  "______uat": "===== 建置 UAT 環境 =====",
  "build-uat": "node scripts/build.js --mode=uat --rootPath=/chat/",

  "______prod": "===== 建置 PRODUCTION 環境 =====",
  "build-prod": "node scripts/build.js --mode=prod --rootPath=/chat/tw/",

},

 

 

接收參數


command-line-args 組件幫忙,我們可以更輕易的解析傳入參數;在 build.js 收到 mode 與 rootPath 參數後將其存放於 process.env 全域變數中,讓其他檔案也可以取得這些資訊。

// 定義 build.js 的傳入參數
const optionDefinitions = [
  { name: 'mode', type: String},
  { name: 'rootPath', type: String},
]

// 接收及格式化傳入參數
const commandLineArgs = require('command-line-args')
const options = commandLineArgs(optionDefinitions)

// 將參數存入 process.env 全域變數
process.env.MODE = options.mode
process.env.ROOT_PATH = options.rootPath

 

 

設定 public path


在透過 webpack 打包程式時,有個 public path 參數特別重要,當你的網站佈署在 sub directory 中,就必須設定此項參數,否則 index.html 中引入 css 及 js 的路徑都不會正確指到 sub directory 中的對應位置。

我們可在 webpack.config 中設定當目前環境是 production 時,將 public path 調整為從外部傳入的 process.env.ROOT_PATH 作為取代,這樣只要透過建置語法的調整就可以輕易指定對應環境的參數。

 

 

設定 constant


接著就是處理常數的部分,筆者希望在程式執行期間取得目前 process.env.MODE 資訊,以此判斷哪個環境去執行哪些行為,因此需要透過 webpack 的 DefinePlugin 來達成;他的概念就是先定義參數於此,在打包的時候會將代碼中有這些定義代碼轉換為該值。

Define Plugin 作用可想像把程式碼 'process.env.MODE' 直接取代為該值 ( 'uat' or 'prod')

 

因此在常數的使用上就只要用 switch 來訂定各個環境所需要使用的特定常數值即可。

 

 

設定 version info


若你的版本號是依照 package.json 中的 version資訊來識別,也可以如法炮製在 webpack 的 DefinePlugin 定義從 package.json 中取得的版本號。

 

假設目前是 v0.6.0 版

 

直接印出版本號時,該值確實如我們設定的版號呈現囉!

 

 

 


希望此篇文章可以幫助到需要的人

若內容有誤或有其他建議請不吝留言給筆者喔 !