表达结合Webpack的全栈自动刷新

  

在以前的一篇文章自动刷新从BrowserSync开始中,我介绍了BrowserSync这样一个出色的开发工具。通过BrowserSync我感受到了这样一个理念:如果在一次ctrl + s保存后可以自动刷新,然后立即看到新的页面效果,那会是很棒的开发体验。

  

现在,webpack可以说是最流行的模块加载器(模块打包机)。一方面,它为前端静态资源的组织和管理提供了相对较完善的解决方案,另一方面,它也很大程度上改变了前端开发的工作流程。在应用了webpack的开发流程中,想要继续”自动刷新”的爽快体验,就可能得额外做一些事情。

  

  

本文并不打算介绍webpack, webpack要求静态资源在被真正拿来访问之前,都要先完成一次编译,即运行完成一次webpack命令,因此,自动刷新需要调整到适当的时间点。也就是说,修改了css等源码并保存后,应该先触发一次webpack编译,在编译完成后,再通知浏览器去刷新。

  

  

现在有这样的一个应用了webpack的表达项目,目录结构如下:

  

, 表达结合Webpack的全栈自动刷新

  

其中,客户端内是前端的静态资源文件,比如css,图片以及浏览器内使用的javascript.server内是后端的文件,比如表达的路线,视图以及其他用节点执行的javascript。根目录的app.js,就是启动表达的入口文件了。

  

开发的时候我们会怎样做呢?

  

先启动表达服务器,然后在浏览器中打开某个页面,接下来再编辑源文件。那么,问题就来了,比如我编辑.scss源文件,即使我只改了一小点,我也得在命令行里输入webpack等它编译完,然后再切到浏览器里按一下F5,才能看到修改后的效果。

  

再比如,我修改了路线里的js文件想看看结果,我需要到命令行里重启一次表达服务器,然后同样切到浏览器里按一下F5。

  

这可真是太费事了。

  

所以,我们要让开发过程愉快起来。

  

  

我们希望的Express& Webpack项目的开发过程是:

  
      <李>如果修改的是客户端里的css文件(包括.scss等),保存后,浏览器不会整页刷新,新的样式效果直接更新到页面内。   <李>如果修改的是客户端里的javascript文件,保存后,浏览器会自动整页刷新,得到更新后的效果。   <李>如果修改的是服务器里的文件,保存后,服务器将自动重启,浏览器会在服务器重启完毕后自动刷新。   
  

经过多次尝试,我最终得到了一个实现了以上这些目标的项目配置。接下来,本文将说明这个配置是如何做出来的。

  

  

首先,webpack已经想到了开发流程中的自动刷新,这就是webpack-dev-server。它是一个静态资源服务器,只用于开发环境。

  

一般来说,对于纯前端的项目(全部由静态html文件组成),简单地在项目根目录运行webpack-dev-server,然后打开html,修改任意关联的源文件并保存,webpack编译就会运行,并在运行完成后通知浏览器刷新。

  

和直接在命令行里运行webpack不同的是,webpack-dev-server会把编译后的静态文件全部保存在内存里,而不会写入到文件目录内。这样,少了那个每次都在变的webpack输出目录,会不会觉得更清爽呢?

  

如果在请求某个静态资源的时候,webpack编译还没有运行完毕,webpack-dev-server不会让这个请求失败,而是会一直阻塞它,直到webpack编译完毕。这个对应的效果是,如果你在不恰当的时候刷新了页面,不会看到错误,而是会在等待一段时间后重新看到正常的页面,就好像“网速很慢”。

  

webpack-dev-server的功能看上去就是我们需要的,但如何把它加入到包含后端服务器的表达项目里呢?

  


  

  

表达本质是一系列中间件的集合,因此,适合表达的webpack开发工具是webpack-dev-middleware和webpack-hot-middleware。

  

webpack-dev-middleware是一个处理静态资源的中间件。前面说的webpack-dev-server,实际上是一个小型表达服务器,它也是用webpack-dev-middleware来处理webpack编译后的输出。

  

webpack-hot-middleware是一个结合webpack-dev-middleware使用的中间件,它可以实现浏览器的无刷新更新(热重载)。这也是webpack文档里常说的HMR(热模块替换)。

  

参考webpack-hot-middleware的文档和示例,我们把这2个中间件添加到表达中。

  


  

  

首先,修改webpack的配置文件(为了方便查看,这里贴出了webpack.config.js的全部代码):

表达结合Webpack的全栈自动刷新