结合Webpack的Express全栈自动刷新
在之前的一篇文章中,自动刷新从BrowserSync开始,我介绍了BrowserSync作为一个优秀的开发工具。通过BrowserSync,我感受到了这样一个想法,保存ctrl s一次后能自动刷新,然后马上看到新的页面效果,这将是一个很棒的开发体验。
目前,webpack可以说是最受欢迎的模块bundler。一方面为前端静态资源的组织管理提供了相对完善的解决方案,另一方面也在很大程度上改变了前端开发的工作流程。在使用webpack的开发过程中,如果你想继续“自动刷新”的刷新体验,你可能需要做一些额外的事情。
Webpack和自动刷新
本文不打算介绍webpack。webpack要求静态资源在被访问之前应该编译一次,也就是说,webpack命令应该运行一次。因此,需要将自动刷新调整到适当的时间点。也就是说,修改完css等源代码并保存后,我们应该触发一次webpack的编译,编译完成后再通知浏览器刷新。
发展快递项目中的问题
有这样一个应用了webpack的Express项目,目录结构如下:
其中,客户端是前端的静态资源文件,比如浏览器中使用的css、图片和javascript。服务器包含后端文件,如快速路由、视图和节点执行的其他javascript。根目录中的app.js是启动express的入口文件。
开发的时候我们会怎么做?
首先启动快速服务器,然后在浏览器中打开一个页面,然后编辑源文件。然后,问题来了。例如,如果我编辑的源文件。scss,即使我只修改了一点点,也要在命令行中输入webpack等待编译,然后剪切到浏览器中按F5才能看到修改后的效果。
再举一个例子,我修改了。js文件中查看结果。我需要在命令行上重新启动Express服务器,然后将其剪切到浏览器中并按F5。
这真的太麻烦了。
因此,我们应该让开,玩得开心。
改进目标
我们想要的ExpressWebpack项目的开发过程是:
如果css文件(包括。SCS等。)在客户端被修改后,浏览器保存后不会刷新整个页面,而新的样式效果会直接更新到页面。如果客户端中的javascript文件被修改,浏览器保存后会自动刷新整个页面,并得到更新后的效果。如果服务器中的文件被修改,服务器保存后会自动重启,服务器重启后浏览器会自动刷新。经过多次尝试,我终于得到了一个达到上述目标的项目配置。接下来,本文将解释如何进行这种配置。
从网络包开发服务器开始
一开始,webpack在开发过程中就想到了自动刷新,这叫做webpack-dev-server。它是一个静态资源服务器,只用于开发环境。
一般来说,对于一个纯前端项目(全部由静态html文件组成),只需在项目的根目录下运行webpack-dev-server,然后打开html,修改任何关联的源文件并保存,然后webpack编译就会运行,运行后通知浏览器刷新。
与直接在命令行上运行webpack不同,webpack-dev-server将所有编译后的静态文件保存在内存中,但不会将它们写入文件目录。这样,没有每次都在变化的webpack输出目录,会不会感觉更清爽?
如果在请求静态资源时webpack编译没有完成,webpack-dev-server不会使请求失败,而是会阻止它,直到webpack编译完成。对应的效果是,如果在不合适的时间刷新页面,不会看到错误,但等待一段时间后会再次看到正常页面,就像“网速很慢”一样。
webpack-dev-server的功能看起来是我们需要的,但是如何用后端服务器添加到Express项目中呢?
网络包-开发-中间件和网络包-热中间件
表达本质是一系列中间件的集合,因此,适合表达的工具开发工具是网络包-开发-中间件和网络包-热中间件。
网络包-开发-中间件是一个处理静态资源的中间件。前面说的网络包-开发-服务器,实际上是一个小型表达服务器,它也是用网络包-开发-中间件来处理工具编译后的输出。
网络包-热中间件是一个结合网络包-开发-中间件使用的中间件,它可以实现浏览器的无刷新更新(热重装).这也是工具文档里常说的HMR(热模块更换).
参考网络包-热中间件的文档和示例,我们把这2个中间件添加到表达中。
工具配置文件部分
首先,修改工具的配置文件(为了方便查看,这里贴出了webpack.config.js的全部代码):
var web pack=require(' web pack ');var path=require(' path ');var公共路径=' http://localhost :3000/';var HotMidleWarescript=' web pack-hot-中间件/客户端?reload=true ';var devConfig={ entry : { page 1:[]./client/page1 ',hotMiddlewareScript],第2:页[./client/page2 ',hotMiddlewareScript] },output: { filename: ' ./[name]/bundle.js ',path: path.resolve(' ./public ')、publicPath: publicPath }、devtool:“源映射”、模块: {加载器:[{ test :/\ .(png|jpg)$/,loader: 'url?limit=8192 context=客户端名称=[路径][名称]。[ext]' },{ test: /\ .scss $/loader : '样式!css?sourceMap!解析url!萨斯. sourceMap' }] },插件:[新webpack。优化。occurrenceorderplugin(),新的web包.HotModuleReplacementPlugin(),新的网络包.NoErrorsPlugin()]};module.exports=devConfig这是一个包含多个进入的较复杂的例子。其中和网络包-热中间件有关的有两处。一是插件的位置,增加3个插件,二是进入的位置,每一个进入后都增加一个hotMiddlewareScript。
hotMiddlewareScript的值是网络包-热中间件/客户端?reload=true,其中?后的内容相当于为网络包-热中间件设置参数,这里重新加载=真的意思是,如果碰到不能热重装的情况,就整页刷新。
在这个配置文件中,还有一个要点是publicPath不是/这样的值,而是http://localhost:3000/这样的绝对地址。这是因为,在使用?sourceMap的时候风格加载器会把钢性铸铁的引入做成这样:
这种一滴的形式可能会使得钢性铸铁里的url()引用的图片失效,因此建议用带超文本传送协议(超文本传输协议的缩写)的绝对地址(这也只有开发环境会用到)。有关这个问题的详情,你可以查看开源代码库上的问题。
表达启动文件部分
接下来是表达启动文件内添加以下代码:
var webpack=require('webpack '),webpackDevMiddleware=require(' web pack-dev-middleware '),webpackHotMiddleware=require(' web pack-hot-middleware '),webpackDevConfig=require(' ./web pack。配置。js’);定义变量编译器=web pack(WebPACkdevconfig);//将serverapp.use附加到编译器(webpackDevMiddleware(编译器,{ //公共路径应该与webpack配置公共路径: webpackkdevconfig。输出。公共道路相同,noInfo: true,stats : { colors 3360 true } });app.use(webpackHotMiddleware(编译器));以上这段代码应该位于表达的路线代码之前。其中,网络包-开发-中间件配置的publicPath应该和工具配置文件里的一致。
网络包-开发-中间件和网络包-热中间件的静态资源服务只用于开发环境。到了线上环境,应该使用express.static()。
到此,客户端部分的目标就完成了。现在到网页里打开控制台,应该可以看到[HMR]连接的提示。这个项目中我只要求钢性铸铁使用HMR,如果你希望爪哇岛描述语言也使用HMR,一个简单的做法是在进入文件内添加以下代码:
if(模块。hot){模块。很热。accept();}这样,与这个进入相关的所有。射流研究…文件都会使用热重装的形式。关于这一点的更多详情,请参考热模块更换。
接下来是计算机网络服务器部分。
重装和监督
服务器部分的自动刷新有一个问题:自动刷新的消息通知依赖于浏览器和服务器之间的web socket连接,但是如果在服务器部分修改了代码,一般需要重新启动服务器才能使更改生效(比如修改路由),这会断开web socket连接。
因此,这就需要一个灵活的策略:浏览器增加一个web socket断开的处理,如果web socket断开,它会启动一个比服务器重启时间稍长的定时器任务,相当于等待服务器重启,然后再次刷新整个页面。
Reload是一个应用这个策略的组件,它可以帮助我们在服务器重启时处理浏览器刷新。
现在,还有一个文件要侦听服务器,如果有任何变化,请重新启动服务器的组件。参照reload的推荐,我们选择主管。
下面介绍快速项目中的重新加载和管理。
侦听文件以重新启动服务器
使用以下代码安装主管(是,要求使用-g):
然后,在包中设置新的脚本。
scripts ' : { ' start ' : ' cross-env node _ env=dev supervisor -i client app ' }这里的主要变化是从node app改为supervisor-I client app。我等于忽略,也就是忽略客户。显然,我们不希望前端代码改变时服务器重启。
这里的Cross-env也是一个npm组件,可以处理windows和其他Unix系统之间设置环境变量的不一致写入。
将重新启动的服务器与浏览器相关联
修改快速启动文件的最后一部分,如下所示:
var reload=require(' reload ');var http=require(' http ');var server=http . CreateServer(app);重装(服务器、app);server.listen(3000,function(){ console . log(' App(dev)现在正在端口3000上运行!');});Express启动文件的结尾通常是app.listen()。根据reload的描述,需要用http添加另一层服务。
然后,在底部向Express的视图文件视图添加一个脚本:
% if (env!==' production '){ % script src=' http :/reload/reload . js '/script % } %所有视图都需要这样一段代码,所以最好通过include或者借助模板引擎进行扩展,将其添加到公共场所。
这里的reload.js和之前webpack的开发环境bundle.js没有冲突。其中一个负责编译和刷新更改后的前端源文件,另一个负责在服务器重启时触发延迟刷新。
此时,服务器就完成了。现在,修改项目中的任何源文件,按ctrl+s,浏览器中的页面将被适当刷新。
完整的例子
完整的示例已提交给github:express-web pack-full-live-reload-示例
效果如下:
其他选项
上面提到的服务器分为视图和路由。如果只修改视图,不需要重启服务器,可以直接刷新浏览器。
鉴于这样的开发场景,可以更快地修改和刷新视图文件。此时,我们不用重载和supervisor,而是使用browsersync,并在Express的启动文件中进行以下修改:
var bs=require('browser-sync ')。create();app.listen(3000,function(){ bs . init({ open : false,ui: false,notify: false,proxy: ' localhost:3000 ',files: [)。/server/view/* * '],port : 8080 });console.log('App (dev)将在端口8080上运行(通过browsersync)。');});然后,使用browsersync提供的新访问地址。这样,在修改视图(html)时,直接借助browsersync进行刷新,在修改css和javascript时,继续由webpack中间件进行编译和刷新。
结论
有了webpack,没有自动刷新怎么工作?
说起来,大概是因为Express和Webpack都是javascript,可以很容易的组合和协作。
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。
版权声明:结合Webpack的Express全栈自动刷新是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。