前言
一個前端工程從開發到上線務必會執行在多種環境中,同時會對環境變數進行相應的配置,如果使用人力去對這些變數進行維護,那麼必然會出現錯誤,所以這個功能交給 webpack 去做最為合適。
webpack相關功能簡介
webpack配置項中有一個mode選項,可配置的有 production development 兩個選項,標識這次打包是用於什麼模式,在專案程式碼中可使用如下程式碼進行讀取:
if (process.env.NODE_ENV === 'production') {
BASE_URL = 'https://host/production/api'
} else if (process.env.NODE_ENV === 'development') {
BASE_URL = 'https://host/development/api'
}
複製程式碼
使用此方式,可以分別對生產和開發模式的api分別進行配置,而不需要每次打包都進行修改,如果需要向程式中新增其它的變數,那麼可以使用 webpack.DefinePlugin 來進行個性化定製,使用方式如下:
// webpack.base.js
const webpack = require('webpack')
webpackConfig = {
plugins: [
new webpack.DefinePlugin({
SOME_CONFIG: `"localhost"`
})
]
}
複製程式碼
其中需要注意的一點是 '"localhost"', 如果是定義一個字串,那麼需要雙重引號包裹。
vue工程的環境變數配置
如果使用vue cli3進行專案初始化,也可以很方便的進行環境配置,具體說明請看官方說明cli.vuejs.org/zh/guide/mo…
但是這種配置具有一定的侷限性,按照文件來看最多隻能支援到三種環境,一旦工程超出三種執行環境,那麼 vue cli 就無法支援到了,所以自定義一套環境配置方案更利於擴充套件。
後續更新
經評論的同學提示,再仔細看了看官方文件,貌似是可以支援超過三種環境配置的,囧,不過這個配置思路是可以運用到其它工程中,所以還是保留文章。
webpack-chain
因為 vue cli3 對 webpack 進行了高度的封裝,所以沒辦法像 vue cli2 一樣隨意的修改源配置檔案,但是 cli3 丟擲了 webpack-chain 來對預設配置進行個性化定製,用法示例如下:
// vue.config.js
chainWebpack: config => {
config.module
.rule('js')
.exclude
.add(/\.min\.js$/)
.end()
config
.output
.set('filename', `js/[name].[hash:8]-v${__VERSION__}.js`)
.set('chunkFilename', `js/[id].[hash:8]-v${__VERSION__}.js`)
}
複製程式碼
在進行配置之前,先看看 vue cli 對於環境變數這一塊是如何配置的, 在工程根目錄執行:
vue inspect > output.js
會生成一個output.js檔案,開啟後滾動到最底部,在1080行左右可以看到這樣一個配置:
/* config.plugin('define') */
new DefinePlugin({
'process.env': {
NODE_ENV: '"development"'
}
})
複製程式碼
修改這個配置,就能向程式中新增其它的環境變數。
egg.js的環境變數配置
最近在使用 egg.js 時感受到了 egg 環境變數配置帶來的便利,具體看這裡,於是決定模仿egg的做法,將此方案整合到 vue cli3 中。
環境的區分
對於配置的修改後面再進行講解,先講解如何區分不同的環境。對於環境的區分,可以在執行打包命令時預先設定一個標籤,這裡可以使用 cross-env 來進行設定 vue cli 的環境變數,程式碼示例如下:
{
"scripts": {
"serve": "cross-env run_server=development vue-cli-service serve -mode development",
"build": "npm run build:dll && cross-env run_server=production vue-cli-service build --no-clean",
"build:UAT": "npm run build:dll && cross-env run_server=uat vue-cli-service build --no-clean",
}
}
複製程式碼
這裡為 run_server 定義了三種不同的值 development、 production、 uat,分別對應不同的服務環境,那麼在打包時,只要執行不同的 script 指令碼就能獲取到相關的環境變數並新增到構建程式中。
環境變數的配置
在工程根目錄建立如下檔案:
簡單的配置示例:
// development_server.json
{
"VUE_APP_RUN_ENV": "DevelopmentServer",
"SERVER_IP": "/api",
"DEV_PORT": 80,
"SERVER_DOMAIN": "www.google.com",
"PROXY_TARGET_IP": "http://192.168.2.236:8989"
}
複製程式碼
在 vue.config.js 中新增如下程式碼
const RUN_SERVER = process.env.run_server || 'development'
const DefaultENVConfig = require('./env_config/default.json')
const serverEnvConfig = Object.assign({}, DefaultENVConfig, require('./env_config/' + RUN_SERVER + '_server.json'))
複製程式碼
通過傳入的目標環境,獲取到對應的配置檔案。同時使用 Object.assign 函式,將目標環境配置與預設環境配置合併得到最終的環境變數配置,再使用 webpack-chain 將之寫入webpack打包配置:
// vue.config.js
module.exports = {
chainWebpack: config => {
config.plugin('define').tap(args => {
for (let i in serverEnvConfig) {
args[0]['process.env'][i] = `"${serverEnvConfig[i]}"`
}
return args
})
}
}
複製程式碼
就這樣,很簡單的程式碼實現了多環境配置,如果需要新增一個全新的環境,那麼只需要新增一個配置檔案,同時將配置檔名設定到打包命令中就行了。