背景
webpack打包配置,根據環境不同判斷不同的參數,采用的是項目中建一個.env文件,create-react-app
中讀取了此文件中的配置並通過DefinePlugin
存到了process.env
中。
new webpack.DefinePlugin({
...env.stringified //這里去讀取的具體配置
})
上線編譯過程中,如果涉及到部署多個不同的環境,需要手動修改.env文件,所以根據npm/yarn自定義參數來解決。
process.argv
nodejs提供了process.argv
來獲取npm/yarn的命令參數
The process.argv property returns an array containing the command line arguments passed when the Node.js process was launched. The first element will be process.execPath. See process.argv0 if access to the original value of argv[0] is needed. The second element will be the path to the JavaScript file being executed. The remaining elements will be any additional command line arguments.
type: string[]
例如:輸入
$ node process-args.js one two=three four
此時,
process.argv = ['/usr/local/bin/node', '<path>process-args.js', 'one', 'two=three', 'four']
DefinePlugin
DefinePlugin 允許創建一個在編譯時可以配置的全局常量。
每個傳進 DefinePlugin 的鍵值都是一個標志符或者多個用 . 連接起來的標志符
注意,因為這個插件直接執行文本替換,給定的值必須包含字符串本身內的實際引號。通常,有兩種方式來達到這個效果,使用 '"production"', 或者使用 JSON.stringify('production')。
解決方案
如上,create-react-app
中讀取了此文件中的配置並通過DefinePlugin
存到了process.env
中。為了不在使用的時候重復判斷當前環境,分別在webpack.config.dev.js 和webpack.config.prod.js配置相同鍵值的參數
//filterArgs.js
module.exports = function(str){
const argv = process.argv
const result = argv.find(item => item.match(str))
if (result) {
return result.split('=')[1]
}
return null
}
new webpack.DefinePlugin({
...env.stringified,
'process.defineEnv': {
REACT_APP_API: JSON.stringify(filterArgs('-api') || process.env.API_DEV)
}
})
new webpack.DefinePlugin({
...env.stringified,
'process.defineEnv': {
REACT_APP_API: JSON.stringify(filterArgs('-api') || process.env.API_PROD)
}
})
這樣就實現了編譯時,可以直接輸入-api
參數定義環境變量
yarn build -api=http:192.168.1.1
使用時,全局process.defineEnv.REACT_APP_API
可獲取