1。本章概述 在本章节,我们将简要的对webpackdevserver的基本使用做一个演示。通过这个章节,你可以学会如何在自己的项目中使用webpackdevserver。2。webpackdevserver使用 第一步:安装webpackdevservernpminstallwebpackdevserverg 第二步:在项目根目录下配置webpack。config。jsvarpathrequire(path);module。exports{entry:{app:〔。srcmain。js〕},output:{path:path。resolve(dirname,public),publicPath:,filename:bundle。js}}; 其中里面的各项配置,通过前面的章节你应该能够理解,此处不再赘述,如果不懂,可以仔细阅读前面的章节。 第三步:配置package。json中的scripts部分scripts:{build:webpack,start:webpackdevserverinlinehotport3000contentbasepublic,test:echoError:notestspecifiedexit1}, 其中对于script部分不太了解的可以查看我写的package。json中的scripts部分深入讲解。通过配置scripts你可以使用如下命令:npmstart或者npmrunstart 来替换掉:webpackdevserverinlinehotport3000contentbasepublic 当然,如果你不想做替换,依然可以在目录下运行你全局安装的webpackdevserver命令。此时需要的所有配置都已经完成了,启动你的npmrunstart就会启动一个Express服务器,端口号是3000,同时支持HMR,contentBase为我们指定的public。3。webpackdevserver的inline模式与iframe模式 上面的打包实例中你看到我在cli中传入了inline,表示这是内联的打包方式,那么什么是内联的打包方式呢?3。1iframe模式 我们首先看看Express服务器是如何处理iframe模式的:app。get(webpackdevserver,(req,res){res。setHeader(ContentType,texthtml);fs。createReadStream(path。join(dirname,。。,client,live。html))。pipe(res);}); 所以当我们在URL中加入webpackdevserver的路径以后,我们就会返回live。html,我们再看看live。html的内容:!DOCTYPEhtmlhtmlheadmetahttpequivXUACompatiblecontentIEedgemetacharsetutf8metanameviewportcontentwidthdevicewidth,heightdeviceheight,initialscale1。0,userscalableno,minimumscale1。0,maximumscale1。0headbodybodyhtml 其直接返回了webpackdevserverlive。bundle。js。我们看看这个请求Express服务器返回的资源内容:app。get(webpackdevserverlive。bundle。js,(req,res){res。setHeader(ContentType,applicationjavascript);fs。createReadStream(path。join(dirname,。。,client,live。bundle。js))。pipe(res);}); 所以我们最终返回的还是clientlive。bundle。js,我们就来看看live。bundle。js的具体内容。首先它会在页面中创建一个iframe并注册了客户端代码:constonSocketMsg{hot(){hottrue;iframe。attr(src,contentPagewindow。location。hash);},invalid(){okness。text();status。text(Appupdated。Recompiling。。。);header。css({borderColor:96b5b4});errors。hide();if(!hot)iframe。hide();},hash(hash){currentHashhash;},stillok:functionstillOk(){okness。text();status。text(Appready。);header。css({borderColor:});errors。hide();if(!hot)iframe。show();},ok(){okness。text();errors。hide();reloadApp();},warnings(){okness。text(Warningswhilecompiling。);errors。hide();reloadApp();},errors(errors){status。text(Appupdatedwitherrors。Noreload!);okness。text(Errorswhilecompiling。);errors。text({stripAnsi(errors。join())});header。css({borderColor:ebcb8b});errors。show();iframe。hide();},close(){status。text();okness。text(Disconnected。);errors。text(Lostconnectiontowebpackdevserver。Pleaserestarttheservertoreestablishconnection。。。);header。css({borderColor:ebcb8b});errors。show();iframe。hide();}};socket(sockjsnode,onSocketMsg); 这样,当webpack的资源发生变化以后可以通过websocket通知到我们这个主页面。我们看看主页面最重要的一个方法,即reloadApp方法,方法内容如下:functionreloadApp(){如果开启了HMR功能if(hot){status。text(Apphotupdate。);try{iframe〔0〕。contentWindow。postMessage(webpackHotUpdate{currentHash},);}catch(e){console。warn(e);eslintdisableline}iframe。show();}else{status。text(Appupdated。Reloadingapp。。。);header。css({borderColor:96b5b4});try{letold{iframe〔0〕。contentWindow。location};if(old。indexOf(about)0)oldnull;iframe。attr(src,old(contentPagewindow。location。hash));if(old){强制刷新iframe〔0〕。contentWindow。location。reload();}}catch(e){iframe。attr(src,contentPagewindow。location。hash);}}}}); 这个主页面接受到事件以后,通过postMessage将当前打包的hash值发送到我们的内部的iframe。如果开启了HMR,那么iframe会检查资源更新,如果没有开启HMR,那么强制iframe进行刷新。上面讲了很多原理的知识,我们下面给出一个日常实例: 我们的页面被嵌套在一个iframe中,当资源改变的时候会重新加载。只需要在路径中加入webpackdevserver就可以了,不需要其他的任何处理:http:localhost:8080webpackdevserverindex。html 从而在页面中就会产生如下的一个iframe标签并注入cssjsDOM: 这个主页面会请求live。bundle。js,其中里面会新建一个Iframe,你的应用就被注入到了这个iframe当中。同时live。bundle。js中含有socket。io的client代码,这样它就能和webpackdevserver建立的httpserver进行websocket通讯了,并根据返回的信息完成相应的动作。 总之,因为我们的http:localhost:8080webpackdevserverindex。html访问的时候加载了live。bundle。js,其具有websocket的client代码,所以当websocketdevserver服务端代码发生变化的时候会通知到这个页面,这个页面只是需要重新刷新iframe中的页面就可以了。该模式有如下作用:Noconfigurationchangeneeded。(不需要修改配置文件)Niceinformationbarontopofyourapp。(在app上面有informationbar)URLchangesintheapparenotreflectedinthebrowser’sURLbar。(在app里面的URL改变不会反应到浏览器的地址栏中)3。2inlinemode webpackdevserver的客户端入口被添加到文件中,用于自动刷新页面。其中在cli中输入的是:webpackdevserverinlinecontentbase。build 此时在页面中输出的内容中看不到插入任何的js代码: 但是在控制台中可以清楚的知道页面的重新编译等信息: 该模式有如下作用:Configoptionorcommandlineflagneeded。(webpack配置或者命令行配置)Statusinformationintheconsoleand(briefly)inthebrowser’sconsolelog。(状态信息在浏览器的console。log中)URLchangesintheapparereflectedinthebrowser’sURLbar(URL的改变会反应到浏览器的地址栏中)。 每一个模式都是支持HotModuleReplacement的,在HMR模式下,每一个文件都会被通知内容已经改变而不是重新加载整个页面。因此,在HMR执行的时候可以加载更新的模块,从而把他们注册到运行的应用里面。不管是inline模式还是iframe模式,我们都是通过socketjs来连接客户端代码和webpackdevserver的服务端代码,其原理都是一样的。3。本章小结 该本章节中,我们讲解了如何在你的项目中使用webpackdevserver来启动一个Express服务器,同时也分析了webpackdevserver本身具有的inline模式和iframe模式。并深入了讲解了iframe模式的原理,希望你能对webapckdevserver有一个更加深入的了解。文中提到的示例代码你可以点击这里下载。