背景
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', '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.jsmodule.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
可获取