通常來講,我們在使用docker build Nodejs容器時,代碼中就有預設一些參數,作為各個環境的環境變量,例如數據庫的URL等
但作為前端應用react,在編譯了代碼后,生成的代碼使用Nginx代理在瀏覽器中運行,那么注意,在瀏覽器中沒有環境變量這個東西,所以原本在后台Nodejs服務器中的獲取環境變量的方案,在前端React項目中不可用
實際上,process在瀏覽器環境都不存在,它是特定於Nodejs的,在轉換過程中,webpack進程會使用process.env給定的字符串值替換所有出現的內容,這就說明,前端React項目想要獲取參數只能在docker build期間進行配置。
找到一個解決方案,當我們啟動容器時,是可以注入環境變量的特定時刻,然后我們可以從容器內部讀取環境變量。我們可以將它寫入一個文件,該文件可以通過Nginx(或者是React應用程序)提供服務,它使用<script>標簽導入至index.html
所以在那一刻,我們可以運行一個bash腳本,創建一個JavaScript文件,將環境變量被指定為全局Window對應的屬性,將它注入至瀏覽器,以方便我們的應用在全局可用
創建項目,並創建有內容的.env文件
# Generate React App create-react-app react-nginx-variable cd react-nginx-variable # Create default environment variables that we want to use touch .env echo "API_URL=https//default.dev.api.com" >> .env
創建腳本env.sh
#!/bin/bash # Recreate config file rm -rf ./env-config.js touch ./env-config.js # Add assignment echo "window._env_ = {" >> ./env-config.js # Read each line in .env file # Each line represents key=value pairs while read -r line || [[ -n "$line" ]]; do # Split env variables by character `=` if printf '%s\n' "$line" | grep -q -e '='; then varname=$(printf '%s\n' "$line" | sed -e 's/=.*//') varvalue=$(printf '%s\n' "$line" | sed -e 's/^[^=]*=//') fi # Read value of current variable if exists as Environment variable value=$(printf '%s\n' "${!varname}") # Otherwise use value from .env file [[ -z $value ]] && value=${varvalue} # Append configuration property to JS file echo " $varname: \"$value\"," >> ./env-config.js done < .env echo "}" >> ./env-config.js
處理的流程
(1)刪除舊文件,並創建一個新文件。
(2)編寫JS代碼,打開對象文字並將其分配給全局窗口對象。
(3)讀取.env文件的每一行並分成鍵/值對。
(4)查找環境變量,如果設置,則使用其值,否則,使用.env文件中的默認值。
(5)將它附加到我們分配給全局窗口對象的對象
(6)關閉對象文字
然后我們在index.html中<head>中添加以下腳本
<script src="%PUBLIC_URL%/env-config.js"></script>
且在首頁代碼App.js中寫一行代碼
<p>API_URL: {window._env_.API_URL}</p>
然后react項目的package.json中
"scripts": { "dev": "chmod +x ./env.sh && ./env.sh && cp env-config.js ./public/ && react-scripts start", "test": "react-scripts test", "eject": "react-scripts eject", "build": "react-scripts build'" },
然后在本機可以使用yarn dev來運行項目,應該可以看到界面上已經成功獲取到.env文件中的變量
當然,我們也可以修改React項目中的.env文件中的內容,從而在本地來運行看到結果
但當成到SIT/UAT/PROD環境時,使用docker-compose方式運行項目時
version: "3.2" services: web: image: weschen/workbench:20190627.2 ports: - "5000:80" environment: - "API_URL=weschen.production.example.com"
頁面中顯示的,即是weschen.production.example.com
