背景
接着上一篇文章,由于要频繁的将代码上传至测试服务器和开发服务器,下面我用dev和pro来代替。我是这么做的,手动修改ajax的url地址,publicPath和一些其他的dev和pro的不同变量等。能实现,确实很恶心哈,而且极易出错,一方面工作任务紧张,时间少。另一方面我又是个比较懒的人,本来想等工作告一段落,有空闲的时候再去做这些事情,后来在后台朋友的强烈建议下,实在忍无可忍,花了一上午把这个东西搞好了。
解决方案
webpack环境变量 和 defingPlugin插件
definePlugin这个插件可以定义一个global的变量,这个变量可以在业务就是就是js代码中(也就是src的js中)的任何文件被访问到。这样我们就可以轻松的区分dev和pro环境的ajax请求地址和publicPath了。
我是将dev和pro的webpack配置文件分成两个文件了,然后结合打包的时候使用不同的命令
dev.config.js里是这样配置的
new webpack.DefinePlugin({
DEV_MODE: JSON.stringify('development')
})
pro.config.js
new webpack.DefinePlugin({
DEV_MODE: JSON.stringify('production'),
VERSION: version
})
src目录下的一个js的写法
// 创建一个新的axios对象
if(DEV_MODE == 'production'){
var instance = axios.create({
baseURL: 'https://yao.lenovo.com.cn/'
// timeout: 20000,
// withCredentials: false, // 跨域请求是否需要使用凭证
});
}else{
var instance = axios.create({
baseURL:'http://dev.like.lenovopcsd.com/'
// timeout: 20000,
// withCredentials: false, // 跨域请求是否需要使用凭证
});
}
package.json文件的配置项
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev":"webpack --config webpack.config.js --env.dev=development",
"build": "webpack --config webpack.pro.config.js --env.dev=production",
"start": "webpack-dev-server --open",
"server": "node server.js"
},
环境变量
上面的一段代码可以看到—env.dev,这个东西就是配置webpack环境变量的这里在dev和pro环境我分别给赋值development 和 production,这样在webpack的配置文件中我们就可以通过env.dev访问到这个环境变量的值了。
说到这里他家可能问为啥用这个呢,definePlugin不都已经解决了域名和publicPath的问题了吗?
我用这个东西呢,主要是我在dev和pro环境下引入了不同的统计代码js。我需要在模板文件中通过一个变量来区分这两个环境来在script标签使用。
事情是这样的,我需要引入cnzz
<script src="https://s96.cnzz.com/z_stat.php?id=*******"></script>
在dev和pro环境只有id是不一样的,我想把这个id通过HtmlWebpackPlugin的模板替换功能放到模板中,就像下面这个样子:
<script src="https://s96.cnzz.com/z_stat.php?<%= htmlWebpackPlugin.options.cnz_params %>"></script>
然后我想的解决方案就是,通过环境变量传入值,然后在配置文件得到这个值再由HtmlWebpackPlugin的配置项将这个值传到前台,最后就实现了不同环境的控制。
plugins.push(new HtmlWebpackPlugin({
title: titles[k],
template:html, //模板本身的位置
filename:filename, //模板的文件名称,可以带目录,会自动生成目录
chunks:[moduleName[0]], //用于指定允许插入模板的chunks,默认是所有,在多入口的时候需要配置这个,因为每个入口文件名字不同
inject:'body', //文件插入模板的位置
// hash: true, //给文件跟一个hash参数
cnz_params: env && env.dev == 'production' ? 'id=1275452318&web_id=1275452318' : 'id=1275452587&web_id=1275452587'
}));
当然还有其他方法,最简单粗暴的就是依靠最开始说到的defingPlugin定义的变量,将一些值直接挂在window对象上,然后再模板里面写一段js动态加载不同的js也是可以的。
不知道definePlugin定义的变量能否在模板中的script标签中直接使用这个我没有试过,欢迎印证了的朋友留言。