前端自动化构建是当下的热门,我记得2014年的时候,前端的自动化构建,大可能是用在javascript的合并、压缩、语法检查、coffeescript,Sass,LESS转换上,构建工具也有不少,好比ant,grunt,gulp等,二次封装的工具也有不少,好比百度的FIS,国外的Yeoman。2016年之后,随着es6,es7,Node的兴起,前端又发生了翻天覆的变化,特别是移动端的H5最为明显,之前切个图,在PC上预览测试就能够发布的时代,在移动端就不灵验了,在手机端预览至少要搭建一个http服务器,好比http://192.168.0.2/index.html。在手机端输入网址不方全,一般会将网址作成一个二维码,而后用手机扫一下就能够打开预览。咱们每改一下样式,就在手机上点一下刷新或电脑上按一下F5,这在最初的时候,也不以为有什么问题,由于拿到我手上的静态页,一般由切片的同事作好了兼容性测试,须要一边刷新浏览器,一边改样式的机会很少。随着咱们尝试用Less,stylus,这样的css工具,一方面,须要用到gulp这样的工具在后台自动监听咱们的样式改动,另外一方面,手动刷新的时候,gulp的脚本未必转换完了。这时候迫切须要浏览器自动刷新。javascript
总的来讲,需求就两点,一是须要一个http服务器,来供手机访问静态资源,另外一个是监听代码的改动并自动刷新浏览器。要知足这两个需求的第三方工具,应当不难找,事实上像fis,yeoman,vuecli这样的工具应当均可以作到。但是我以为它们都太复杂了,虽然我只用到其中一点点功能,可是我不得不仔细的通读他们的文档,找到本身须要的功能。有时候,官方说三分钟入门,但是我花三十分钟了尚未入门。或许我几天以后,我好不容易入门了,结果周围同事又给我推荐另外一个工具,说比我手上这好一千倍,因而我又去学另外一个工具。如此,很容易陷入不一样工具之间的学习。更要命的是,转了一圈回来,其实我用的那一点功能,用哪个工具都差很少,既不像A同窗说的那么差劲,也不像B同窗说的那么好。php
2015年6月份的时候,咱们的项目开始用express+React.js作服务端渲染,Redux作状态管理。咱们搭建了一套开发框架,之前那些自动化的工具,都不能彻底知足个人需求了。js和css的改动愈来愈频繁,并且node不像php代码那样,改动以后,服务器会自动更新,它须要手动重启node进程,另外一方面,自动刷新浏览器,会致使redux的action日志看不到。这个时候,浏览器的自动刷新已经知足不了咱们的需求。咱们须要浏览器在不刷新的状况下,局部更新我改过的代码。这也就是“热替换”(HMR)这个概念的来由。不少新同事搞不清什么是自动刷新,什么是热替换。热替换听起来,有点像是ajax的效果,不过,ajax是点击某个动做或触发某个事件以后由js脚本触发,而“热替换"是在咱们改动了代码的时候触发(也就是CTRL+S保存的时候). 自动刷新就是指不用手动去按F5. css
要实现自动刷新和静态服务器,最简的就是用webpack-dev-server . 若是以前用过webpack,那么webpack-dev-server则很容易接受,若是尚未用过webpack,那么我以为颇有必要去看看。网上有不少介绍webpack及webpack-dev-server的文章,我以为要这实现这个需求,只要两步就能够:html
1.安装webpack-dev-server前端
2. 运行webpack-dev-server --inline --hotvue
webpack.config.js的配置:java
var path = require("path"); var webpack = require('webpack'); //var ExtractTextPlugin = require("extract-text-webpack-plugin"); var node_modules_dir = path.resolve(__dirname, 'node_modules'); module.exports = { entry:[ //'webpack-dev-server/client?http://localhost:8081', //'webpack/hot/dev-server', './src/app.jsx','./src/app.css' ], module: { loaders: [{ test: /\.es6|jsx$/, exclude: [node_modules_dir], loaders: ['react-hot','babel-loader'], }, { test:/\.css$/, loaders:['style', 'css'] }] }, output: { path: path.resolve(__dirname, "dist"), publicPath:"/assets/", filename: 'bundle.js' }, resolve: { extensions: ['', '.js','.es6','.jsx'] }, plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"development"' }), //new webpack.HotModuleReplacementPlugin(), new webpack.NoErrorsPlugin() ] }
经过命令行的方式执行webpack-dev-server , 重点要说的是--hot这个参数,它就是启动热替换用的。它会自动给plugins插入new webpack.HotModuleReplacementPlugin() 所以不须要人为的再配置这个插件了。因此我在webpack.config.js中注释掉了这一行。 而后entry中也不须要加webpack/hot/dev-server和webpack-dev-server/client,记住:命令行方式运行webpack-dev-server会自动替你完成这些工做。不要人云亦云的去添加这些注释的内容,我看到甚至还有用express配合webpack-hot-middleware,webpack-dev-middleware 之类的用法,那更加复杂了,对于只想要实现自动刷新和热替换来讲,命令行方式运行,配合 --hot --inline 这两个参数是最简单有效的作法。其它复杂的配置和用法,有它的特殊的适用场景,好比同时须要两个服务器,一个充当数据接口,一个充当静态文件服务器, 咱们但愿webpack-dev-server经过node API的方式运行。这个有点复杂,用到这么复杂的情形的,通常都是能本身搞定这个配置的。有这方面需求的,参考demo8的代码。 node
extract-text-webpack-plugin这个插件,它能够将模块中的样式部分提出来,单独打包成文件,可是它只适用于生产模式。开始我也没有注意,在开发模式下也用了,还以为很爽,直到有一次,我发现更改样式的时候,浏览器竟然自动刷新了,而我指望是热替换。这时我才理解,只适用于生产模式,不是说它在开发模式下,就不生效了,而是它配合 --hot参数的时候,不会有热替换的效果。react
简单的一行小字,没有细看,结果走了不少弯路。俗话说,方向反了,中止就是进步。 对于普通的js模块来讲,热替换须要本身写loader插件,若是是react,vue则官方会提供热替换的loader,好比react的 react-hot-loader 。若是没有用这些能够支持热替换的插件,那么默认的就是浏览器的自动刷新效果。css的话,只要加上css-loader,style-loader就能够了。最后再补一刀,output:中要配publicPathwebpack
output: { path: path.resolve(__dirname, "dist"), publicPath:"/assets/", filename: 'bundle.js' },
在html中也要写publickPath的地址:
/assets/这个虚拟目录中的文件其实是保存在内存中的,这样就为模块的热替换提供了可能。若是写成实际的产出目录,是怎么也不会看到热替换的效果的,甚至连自动刷新都不会出现.
源码地址:https://github.com/bjtqti/how_to_use_webpack/tree/master/demo18
首先看控制台的提示:
出现这个HMR说明配置方面是对的,可是光有这个还不行,若是模块没有热替换的loader,那么就会触发失败,失败的结果就是致使浏览器刷新。这也是为何有时候明明出现这个热替换的标志了,仍是会出现浏览器刷新。若是添加了支持热替换的loader,那么当咱们保存更改的时候,浏览器只会默默的更新变化区域,而不会产生刷新。同时,控制台的log也会累积,不会被清空。
辛苦作出来的H5页面,在电脑上模拟显示的效果,都未必可靠,最后都须要放到手机上进行真机检测。经过webpack-dev-server生成的http服务器,能够实现经过手机访问。好比电脑的ip是192.168.1.122, 默认状况下,那么经过http://191.168.1.122:8080就能够在手机上打开咱们的H5页面。若是打不开,请检查两个地方:
1. webpack-dev-server 添加 --host 0.0.0.0 参数
2. 保证电脑和手机处于同一个无线网络,即电脑能够ping通手机。
在手机上检测无缺以后,就须要把代码进行合并,压缩,添加hash标记,小图片,字体文件转base64,提取共公代码等等. 一方面能够简单的使用
webpack -p 也可自行配置webpack.config.js,演示:
plugins: [ new webpack.DefinePlugin({ 'process.env.NODE_ENV': '"production"' }), new ExtractTextPlugin('css/[name].css'), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false }, output: { comments: false }, sourceMap: false }), new webpack.optimize.CommonsChunkPlugin('vendor','js/vendor.js'), new webpack.optimize.OccurenceOrderPlugin(true), new webpack.NoErrorsPlugin() ]
到此,整个构建工做就完成了。
关于webpack及webpack-der-server的教程不少,可是不少文章发布的较早,不必定适用你如今用的版本。遇到问题的时候,我建议先看看错误提示,而后查看官方文档。先从简单的用法开始去动手尝试,必定要尝试,不要以为很简单,只在脑海里想固然的运行一遍就觉得学会了,俗话说,实践出真知,一样的问题,不一样的环境(windows/mac/node版本...),会有不一样的状况,只有本身一一去试过了,遇到问题心中有数,才不会慌。最后,要把学到的内容结合实际的项目去运用看看,有哪些功能对目前的开发有帮助,哪些功能还不是很了解,须要更深刻的学习。遇到实在有本身找不到解决办法的问题,再去网上查,我的以为stockoverflow还算比较靠谱。最后,要记得把本身遇到的坑整理成章,分享是一种美德。