學起來會很方便。
簡述
在進入職場前,環境變數對我來說主要是拿來儲存 API Key 之類的東西,一直到了最近我才理解環境變數其實還有另一個用途是「拿來區分不同環境」。
舉例來說,最常見的差異是開發環境和生產環境上的 API 端口可能會不一樣,這時候就很適合用環境變數來設定端口的值。又或者說在不同環境上可能會想呈現一些不同的資訊,這時候也很適合用環境變數來設置。
總而言之,這篇主要是想紀錄一下在 React 上如何使用環境變數。
NODE_ENV
當我們在用 npm run start
、npm run build
、 npm run test
時其實預設會自動來帶入 NODE_ENV
這個環境變數,而這個值會顯示目前的環境是什麼:
- development
- production
- test
換句話說,其實你可以把 react 預設給你的指令想成是這樣:
1 | "scripts": { |
只是這些值是不能修改的,所以在實際情況中你不會看到 NODE_ENV=xxxx
這樣的設定。
來舉個例子,假設我們有底下的 Code:
1 | function App() { |
在 Dev 環境(npm run start
)上跑的結果會是:
在 Production 環境(npm run build
)上跑的結會是:
透過終端上輸入 Env 變數
假設目前的 Code 長這樣:
1 | function App() { |
為了讀取到 REACT_APP_DEMO_CODE
這個變數,我們可以在執行 react-script
之前把變數寫進去:
或者是寫在 package.json
中(兩個背後的執行方式是一樣的):
1 | "scripts": { |
這邊的執行結果長這樣:
透過 .env 檔案來輸入變數
Create React App 預設會自動存取這幾個 .env 檔案:
.env
:可以在所有環境中存取,除了 test.env.local
:可以在所有環境中存取,除了 test(更強的優先權).env.development
,.env.test
,.env.production
:可以在指定的還境中存取.env.development.local
,.env.test.local
,.env.production.local
:可以在指定的還境中存取(更強的優先權)
所以你只要建立符合這些名稱的檔案以後,就可以直接在專案中存取到這些 Env 變數。
會分成這麼多的原因主要是為了針對不同環境來讀取不同的 Env 變數,等一下會在解釋他們實際的差別,這邊先來看個示範。
首先在根目錄建立 .env
檔案,並填入底下內容:
1 | REACT_APP_DEMO_CODE='Hello PeaNu' |
接著就能存取到這個變數了:
順道一提,因為這邊示範用的是 .env
檔案,所以不管是 development 或 production 都可以存取這個變數。
所以這幾個檔案的差別在哪?
我們先來看官方文件,它其實有提到每個 .env
檔案之間的「優先權」:
npm start
: .env.development.local, .env.local, .env.development, .envnpm run build
: .env.production.local, .env.local, .env.production, .envnpm test
: .env.test.local, .env.test, .env (note .env.local is missing)
附註:(優先順序是左邊 > 右邊)
舉例來說,如果你的專案同時存在 .env
和 .env.local
時,在 npm run start
的情境下會採用 env.local
的內容,.env
就不會被存取到,其他的也是以此類推。
存取 package.json 中的內容
假設我們的 package.json
有這些內容:
1 | { |
如果我們想透過 .env
來存取這些內容的話,可以用 $
來存取變數:
1 | REACT_APP_VERSION=$npm_package_version |
接著在 Code 裡面存取這些 Env 變數就可以拿到對應的值了:
1 | function App() { |
自定義 .env 檔案
如果你不想要用預設提供的那些 .env
檔案名稱(.env.production
、 .env.development
等等那些),而是想自己取名字,例如說我想建立 .env.dev
和 .env.demo
來分別給 Dev / Demo 環境使用。
1 | // .env.dev |
1 | // .env.demo |
那麼現在會碰到的問題是如果沒告訴 react-scripts
的話,他都吃不到這兩個 .env
檔案的內容。
這時候就可以把 npm script 的部分修改成底下這樣:
1 | { |
附註:注意 sh -ac
後面要執行的指令要放在單引號('
) 中
關於這個 sh -ac
的意思我不想解釋太深,但我自己的理解是:透過 sh
來執行一段 shell。因為我們是直接呼叫 shell,所以有能力把 .env
帶入 process
物件中,並且執行 react-scripts
,詳細可以參考這篇討論。
如果上面聽不懂的話也沒關係,你只要知道透過它我們就可以把指定的 .env
來丟給 react-scripts
執行就好了。
設定好以後執行 npm run start
會得到這樣的結果:
執行 npm run build
以後會得到這樣的結果: