关于这个问题着实让人头疼。对于大型的项目而言,配置太过复杂了。以下是我的需求场景及【解决方案】
由于当前的项目是在开源DEMO的基础上做的。所以里面的很多webpack配置我都不熟,简直让我生不如死。
- 需求
原本的DEMO分成 dev环境和pro环境。
在打包的时候一定是pro环境,这个打包并不是单纯的webpack打包。而是把程序打包成 PC应用【electron】。
原本DEMO的配置,在做这个打包软件的操作中就是设置成 process.env.NODE_ENV=’production’,但是我希望在使用
NODE_ENV=’production’的情况下,再分两种情况。一种是请求我们的测试地址http.dev.com ,另一种是线上地址http.pro.com 。【因为是在DEMO基础上做,所以我不可能去更改原有的配置,里面还涉及了electron的打包配置,而不单单是webpack的打包。否则牵一发动全身,心有余力不足,所以我只能在NODE_ENV为production的情况下在增加一个变量去获取】
刚开始我每次打包软件之前总是去修改配置文件参数,到底是请求 测试地址还是线上地址。再打包,但是这样相当的麻烦。
于是我想通过webpack 命令行的方式去代替我手动更改参数。
为此查到了以下几个方案:【一下方案都没有解决我的情况,但是其中的一些问题还是要说一下】
1、直接在webpack命令行输入参数 –xxx yyy 即配置xxx参数,它的值为yyy,这样,可以通过var argv = require('yargs').argv.xxx;
去获取,但是这种方式,只能在webpack.config.js的配置文件中获取,如果你希望在自己的某一个xx.js文件中调用,执行webpack命令是会报错的。而且,由于webpack版本问题,在4.x 的时候是允许通过 --
的形式去传参的,但是在我的3.12.x版本中,无法这样传参,会报错
2、cross-env模块, npm i -D cross-env 模块,在package.json文件中写上
"build-main": "cross-env NODE_ENV=production http_env=production node --trace-warnings -r babel-register ./node_modules/webpack/bin/webpack --config webpack.config.main.prod.js --colors",
cross-env原本是用于跨平台的命令的。在执行webpack命令之前写上 cross-env xxx=yyy即可配置,那么即可通过process.env.xxx来访问这个变量而不需要引入 yargs等模块。但是根据我测试。貌似只有你的程序在node环境下执行才能全局获取到这个变量,否则在webpack打包的时候,也只能在webpack.config.js文件下拿到,而其他自定义JS文件还是undefined。具体情况可以自己试一试,我有点模糊了,因为查了太多资料。忘记了当时的情况。但它肯定是不符合我的需求的
解决方案
new webpack.DefinePlugin({
http_env:JSON.stringify("parameter")
})
//确保你的变量值是用 JSON.stringify转换的,或者是 '"parameter"'这种形式,打包的时候会把http_env全局变量替换成 "parameter" 所以,双引号需要保留
webpack.DefinePlugin允许你定义全局变量,在自定义文件中访问它。许多人会把这个值付给process.env,比如
new webpack.DefinePlugin({
'process.env':{
http_env:JSON.stringify("parameter")
}
})
这样就可以通过process.env去获取。
但是!
,因为之前说的因为webpack版本的原因,我在3.12.x版本无法通过webpack命令行 通过 --
去自定义传参,否则报错,所以我使用了cross-env模块去传参,那么我在webpack.config.js文件下就可以通过process.env.xxx去获取。结果我写了下面这句
//命令行中的参数(两条命令,不同文件用不同webpack配置文件打包):
//cross-env http_env=development webpack --config xxx.config.js
//cross-env http_env=development webpack --config yyy.config.js
new webpack.DefinePlugin({
'process.env':{
http_env:JSON.stringify(process.env.http_env)
}
})
//结果我在 A.js文件中正常通过process.env.http_env环境拿到了,A.js是通过 xxx.config.js webpack配置文件打包的
//而 B.js 则无法正常获取,B.js是通过yyy.config.js webpack文件打包的
//我想了半天没想明白,毕竟无论是xxx.config.js还是yyy.config.js都是基于
// common.config.js配置文件通过webpack-merge合并的。为什么一个能拿到另一个拿不到呢?
最终我改写成下面这样。
new webpack.DefinePlugin({
http_env:JSON.stringify(process.env.http_env)
})
//我直接去掉了process.env作为key,通过A.js和 B.js自定义文件中的内容也从 process.env.http_env改成了
//http_env,最终的打包效果全都正常输出,说明通过cross-env获取命令行参数再赋值给全局变量是有问题的。
//理论上没什么问题,但很明显它不兼容
到此,折磨我一段时间的webpack配置有了着落了,看来还是跟不上时代啊。当时看webpack还是2.x再用的时候已是4.x