前言:刚接手我们前端这个项目时,项目内部定义两个变量服务器地址和七牛的地址,每次上线,都需要手动去切换这两个地址到生产环境,很不方便。后来,又引入了第三个全局变量,这个时候我就改进了下,专门定义一个环境变量来控制这三个变量的值,这样稍微好了些,但是每次上线还是需要手动去切换,需要非常小心。使用webpack建立开发和生产环境,我们就可以一句命令上线,不用再过多担心。
今天,我们来谈谈在webpack中建立开发和生产环境,下面是我在实践过程中的一些总结,希望给大家能带来一些帮助。
1、定义npm scripts的开发和生产命令,自动打包上线
因为webpack的开发和生产命令不同、参数复杂原因,又因为npm scripts定义命令的简便和钩子功能,所以使用npm定义简单统一的命令成为我们的需要(不了解npm scripts的同学可以先看阮一峰老师的npm scripts 使用指南)。
如下是我在项目用到的一部分命令:
1 2 3 4 5 6 7 8 9 10 11
| { // ... "scripts": { "dev": "env ENV_MODE=dev webpack-dev-server --hot --inline --progress --colors", "predeploy": "echo '******开始构建生产环境的代码*********'", "deploy": "rm -rf dist && ENV_MODE=production webpack --progress --colors --bail --profile", "postdeploy": "echo '******构建成功,开始发布内容*****' && chmod +x publish.sh && ./publish.sh build-master" } }
|
定义好上面内容后:
我们在开发时,只需要运行:
就相当于运行了
1
| env ENV_MODE=dev webpack-dev-server --hot --inline --progress --colors
|
注:上面这句命令,设置了一个指定的环境变量去执行webpack-dev-server命令,后面我们可以在webpack.config.js
中通过process.env.ENV_MODE
获取它的值。
我们需要打包发布上线时,只需要运行:
它就会首先执行pre-deploy
中的命令,输出:
1
| ******开始构建生产环境的代码*********
|
然后,执行:
1
| rm -rf dist && ENV_MODE=production webpack --progress --colors --bail --profile
|
开始打包代码到dist
目录下。
最后,打包完成之后,它会执行post-deploy
中的命令:
1
| echo '******构建成功,开始发布内容*****' && chmod +x publish.sh && ./publish.sh build-master
|
首先输出:
之后,给当前目录下的publish.sh
脚本添加执行权限,并传递build-master
给publish.sh
执行。
publish.sh
的作用是发布上线,它做的事情主要是将dist
中打包好的代码强制发布到对应的分支下,然后服务器利用git的post-receive
钩子自动同步代码到对应目录下,这样就达到了发布上线。
脚本代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #!/usr/bin/env bash cd dist echo $1 #构建代码不能放入打包的代码中 if [ x"$1" == x"" -o "$1" == "dev" -o "$1" == "master" -o "$1" == "test" -o "$1" == "simulate" ]; then echo "代码分支,不要构建" exit -1 fi echo "##### clean git" rm -rf .git echo "##### 初始化git" git init git add . git commit -m "update at `date` " git remote add origin [email protected]:liuchungui/AngularWebpack.git >> /dev/null 2>&1 echo "##### push到$1分支" git branch $1 git checkout $1 git push origin $1 -f echo "##### $1 发布完成"
|
建了一个demo,大家可以下载下来看看AngularWebpack,内部的[email protected]:liuchungui/AngularWebpack.git
可以替换为你的git仓库地址。
2、定义ENV_MODE变量,配置环境
上面的脚本执行,会定义一个环境变量ENV_MODE
,而我们可以在webpack.config.js
文件中获取它的值,然后通过DefinePlugin
插件配置到我们项目中使用,从而达到自动配置开发或生产环境,不需要我们手动设置。
如何配置呢?代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| module.exports = function makeWebpackConfig() { /** * 创建配置对象 */ var config = {}; // ... 省略其它代码 config.plugins = []; config.plugins.push( //配置环境变量 new webpack.DefinePlugin({ ENV_MODE: JSON.stringify(process.env.ENV_MODE), }) ); return config; }();
|
注意: JSON.stringfy一定不能省略,DefinePlugin
插件的作用是将打包的变量ENV_MODE
替换成我们传递给它的值。
这样,我们就可以在代码中像下面这样获取服务器地址:
1 2 3 4 5 6 7 8 9
| // common.js文件 function serverBaseURL() { switch (ENV_MODE) { case "dev": return "http://localhost/api/"; case "production": return "http://api.xxx.com/"; default: return "http://localhost/api/"; } } module.exports = serverBaseURL();
|
当然,你也可以直接使用DefinePlugin
定义ServerBaseURL
的值。
3、只有开发或生产环境应该使用的插件
这里并不是说只有某个环境才能使用,只是强烈建议在某个环境下使用。如代码压缩我们应该只在生产环境下使用,开发环境下使用会影响开发效率,下面是我的一些配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| //生产环境下独有的插件 if (isProd) { config.plugins.push( new webpack.NoErrorsPlugin(), new webpack.optimize.DedupePlugin(), new webpack.optimize.UglifyJsPlugin(), new CopyWebpackPlugin([ { from: __dirname + '/gw/images', to: __dirname + '/dist/gw/images' } ]) } //开发环境下使用的插件 else { // config.plugins.push( // new WebpackBrowserPlugin() // ); }
|
总结
主要说了我们应该定义开发和生产环境的命令,方便我们使用;之后,说了通过DefinePlugin
插件定义开发和生产环境的变量;最后,列出了一些应该在生产环境中使用的插件。
参考
angular-webpack
webpack多页应用架构系列(七):开发环境、生产环境傻傻分不清楚?
npm scripts 使用指南