前端工程化——Livereload和HMR、本地开发服务器

article/2025/10/7 12:48:18

目录

本地开发服务器解决的问题

动态构建

Mock服务

动态构建

源码改动之后,浏览器应该在何时获取重新编译后的资源?

Livereload和HMR


有了构建系统的支持,前端开发人员可以使用诸多有利于开发和维护的技术进行源代码编写。然而如果在开发过程中源码的每次修改都需要执行一次构建才可以在浏览器中调试,这显然非常影响工作效率。要解决这个问题,可以将本地开发服务器与构建系统结合,对源码进行监听并在其修改之后触发动态构建,以自动的方式取代人工。此外,构建系统将源码转化为生产环境可用的文件,主要解决了开发层面的问题。Web开发过程中除开发层面的问题以外,协作同样是影响工作效率的重要因素,最典型的是前端逻辑依赖服务器端异步接口完成情况的串行工作流程。本地开发服务器的另一个主要功能是提供Mock服务以实现前后端并行开发。

本地开发服务器解决的问题

动态构建和Mock服务是本地开发服务器的主要功能。动态构建解决的问题是面向开发层面的,通过监听→修改→触发→构建的流程避免了源码的每次修改都需要人为地执行一次构建,便于开发过程中的即时调试。Mock服务解决的问题是面向前后端协作层面的,以提前约定好的规范为前提,通过本地服务容器提供的Mock数据接口辅助前端逻辑的编写。此外,如果项目需要SSR(服务器端渲染),本地开发服务器还需要具备解析HTML模板的功能,同时Mock服务提供SSR所需的初始数据。

动态构建

动态构建存在的必要性是为了方便前端工程师在开发期间进行即时的调试。我们不妨设想一下没有动态构建场景下的开发流程。

【1】前端工程师编写了一段源码之后,手动执行构建产出目标文件,然后在浏览器中查看效果。

【2】目标文件在浏览器中运行时发现某个CSS属性存在问题。

【3】工程师在浏览器调试面板中修正了问题,然后将修正后的代码写入源代码中,执行构建后再次打开浏览器查看效果。

【4】然而此次构建后的目标文件仍然存在问题,工程师不得不重复着调试→修改源码→手动构建→调试的工作。

前端开发过程中需要非常频繁的调试,尤其是CSS效果的实现,每次修改源码后手动执行构建势必会拖慢工作效率。动态构建的作用是通过自动构建取代人工,减少前端工程师开发之外的精力消耗。如果把构建比喻为将宿主环境不识别的源码加工成可运行代码的加工机器,那么动态构建就是连接源码与加工机器的管道。这条管道有两个功能模块:监听和触发。管道开启期间,源码的任何修改行为都会被监听模块侦测到,然后触发模块唤起构建这台加工机器对改动后的源码进行加工。

Mock服务

动态构建为前端工程师单方面开发提供了便利,Mock服务针对的是前后端开发人员协作过程中,部分前端逻辑开发必须以服务器端数据接口完成为前提,造成整体团队开发周期翻倍的问题。前端工程师使用本地服务器提供的Mock数据接口,在服务器端开发的同时进行前端逻辑的并行开发,待服务器端接口开发完成之后将接口的请求地址从Mock服务迁移至服务器端环境即可。Mock服务能够发挥作用的必要前提是前后端开发人员在正式进入开发之前协商好数据接口的规范,这不仅仅是技术层面的问题。前面章节我们也提到过,前端工程体系不仅仅需要技术的支持,同样也包括人员沟通上的规范。

如果你的项目不是完全前后端分离的,则仍然需要依赖服务器端渲染HTML,并且本地开发服务器使用与服务器端同样的编程语言,那么Mock服务还需要具备SSR功能,包括以下两点。【1】支持与服务器端相同的HTML模板引擎。【2】SSR所需的Mock数据。

综上所述,Mock服务等同于正式服务器的一个替代品,但是仅具备前端所需的基本功能(异步接口和SSR),与前端逻辑无关的功能(比如数据库操作、缓存层、Session管理等)不在Mock服务的范畴内。与构建系统相比,本地开发服务器要解决的问题非常明确。

动态构建

动态构建,或者叫作动态编译(Dynamic compilation),最早来源于Self语言,使用此技术最广为人知的是Java。前端工程体系中所谓的动态编译与Java中的同名概念并不相同,应用于Java的动态编译最普遍的是即时编译(JIT),将部分代码的编译行为推迟到运行时执行,目的是为了提高性能。而我们在此讨论的动态编译并没有那么复杂,按前文所述,本地开发服务器动态编译功能的目的是为了节省人力、方便前端开发和调试,本质原理是监听+触发。webpack-dev-server是官方提供的用于搭建本地开发环境的一个微型Node.js服务框架,并且提供动态编译、HMR(热更新)等功能。如果你的项目不需要Mock服务,webpack-dev-server完全可以满足需求。但是Mock服务是本地开发服务器不可或缺甚至可以说是最重要的功能,不能舍弃。幸运的是,webpack同时提供了webpack-dev-middleware,它是Express框架的一个中间件,结合一些必要的功能模块可以实现动态编译以及热更新等功能。

源码改动之后,浏览器应该在何时获取重新编译后的资源?

这似乎是一个显而易见的问题,你可能会不假思索地回答:当然是在重新编译行为完成之后。那么我们如何知道重新编译何时完成呢?难道一直盯着命令行窗口直到获得输出编译完成的日志吗?前端工程体系的原则之一是能够自动化的工作就不要消耗人力,这种人工“盯梢”的方式显然违背了这条原则。在webpack发布之前,业界大多数工具对此问题的解决方案是:在动态编译完成之后立即触发浏览器自动刷新,从而让浏览器及时获取重新编译之后的资源,这种方案被称为Livereload。webpack使用了一种效率更高且更利于调试的解决方案:Hot Module Replacement,简称HMR。接下来,我们一起探讨Livereload和HMR的区别以及如何在本地开发服务器中综合HMR和Livereload以保证浏览器即时获取动态编译资源。

Livereload和HMR

Livereload

Livereload的原理是在浏览器和服务器(本地开发服务器)之间创建WebSocket连接,服务器端在执行完动态编译之后发送reload事件至浏览器,浏览器接收到此事件之后刷新整个页面,流程如图所示。

Livereload虽然能够保证动态构建的资源被浏览器即时获取,但是它有一个致命的缺陷:无法保存页面状态。举个例子,调试是编写CSS最重要的一个环节,因为CSS没有逻辑性可言,即使是专家级的CSS开发者也不能保证不经调试编写的CSS在浏览器中得到预期的效果。所以几乎所有的CSS编写工作都是先通过浏览器调试面板查看效果,然后将代码写入源文件中的。此外,复杂的CSS效果可能并不是一个HTML元素便可以实现的,往往是需要多个元素配合的综合方案。那么请设想下面这样的场景。

【1】通过浏览器调试面板实现一个复杂的CSS效果,涉及的HTML元素个数为5个。

【2】在将CSS代码写入源文件的过程中,在写入第4个元素的CSS代码之后不小心保存了源文件,或者干脆就遗漏了一个元素的代码。

【3】源文件修改保存之后立即触发了动态构建,构建完成之后触发Livereload。

【4】页面刷新之后由于源文件中缺少了一个元素的CSS代码,导致UI乱作一团。

之所以出现上述场景的原因有两个,一是因为浏览器调试面板中的代码是临时性的,页面刷新之后便被清空;二是由于开发人员的马虎大意。你可能会说人为的失误完全可以避免,然而在实际开发中,这种“低级错误”反而是严重影响工作效率的因素之一。之所以建立前端工程体系的原因之一,便是在开发阶段允许一定的容错空间,在产出阶段对质量严格把控。所以,我们在搭建工程体系各个功能模块期间不能因为人为失误是技术层面外的因素而忽略了它对工程效率的影响。

即便不考虑人为失误,Livereload对于一些需要复杂的操作流程才可展示的组件同样有影响。比如一个弹窗组件需要操作三四步才会展示,浏览器刷新之后必须重复完整的操作流程才可以看到修改后的效果。HMR以局部更新取代整体页面刷新,有效地弥补了Livereload无法保存页面状态的缺陷。

HMR

HMR工作流程在开启webpack-dev-server模式下,webpack向构建输出的文件中注入了一项额外的功能模块——HMR Runtime。同时在服务器端也注入了对应的服务模块——HMR Server。两者是客户端与服务器端的关系,与Livereload的实现方式类似的是,两者之间也是通过WebSocket进行通信的。HMR热更新的流程如图所示。

【1】修改源文件并保存后,webpack监听到Filesystem Event事件并触发了重新构建行为。

【2】构建完成之后,webpack将模块变动信息传递给HMR Server。

【3】HMR Server通过WebSocket发送Push信息告知HMR Runtime需要更新客户端模块,HMR Runtime随后通过HTTP获取待更新模块的内容详情。

【4】最终,HMR Runtime将更新的模块进行替换,在此过程中浏览器不会进行刷新

以上流程虽然看上去非常清晰明了,但其中有许多技术细节值得品味,比如HMR Server以何种形式的文件将信息传递给Runtime, Runtime又是如何替换模块内容并且立即生效等。其中涉及webpack内部细节以及浏览器原理的部分知识,可以自行查阅相关资料

Express集成HMR功能
webpack-hot-middleware是可实现HMR的中间件,用于Express服务器端集成,集成方式很简单,只需在webpack-dev-middleware之后接入HMR中间件即可。


http://chatgpt.dhexx.cn/article/qXsvt9NN.shtml

相关文章

hmr webpack 不编译_webpack hmr

参考: hmr技术支持程序运行时的模块(amd、commonJS等)的修改、添加和删除,而不用整个程序重新加载,这可以提升开发的效率: hmr后程序的状态可以得到保存 仅仅改变变化的部分,其余不变 调样式更加快捷,基本比…

18.webpack4之HMR

1.HMR(Hot Module Replacement)热模块替换 在开发环境,可以使用热模块替换(HMR)去实现如果一个模块发生变化,只会重新打包这一个模块(而不是所有模块都进行打包),而无需重…

webpack5之HMR原理探究

一、概念介绍 模块热替换(hot module replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允许在运行时更新所有类型的模块,而无需完全刷新。 主要是通过以下几种方式,来显著加快开发速度: 保留在完全重新加载页面期间丢失的应用程…

hmr webpack 不编译_一文搞懂 webpack HMR 原理

关注「前端向后」微信公众号,你将收获一系列「用心原创」的高质量技术文章,主题包括但不限于前端、Node.js以及服务端技术 一.HMR Hot Module Replacement(HMR)特性最早由 webpack 提供,能够对运行时的 JavaScript 模块进行热更新(无需重刷&a…

Webpack HMR 原理全解析

执行 npx webpack serve 命令后,WDS 调用 HotModuleReplacementPlugin 插件向应用的主 Chunk 注入一系列 HMR Runtime,包括: 用于建立 WebSocket 连接,处理 hash 等消息的运行时代码 用于加载热更新资源的 RuntimeGlobals.hmrDow…

vite1.x 热更新(HMR)的实现原理

前言 将近一年前自己尝试阅读vite源码(2.x),虽然也有些收获但整体并没有到达我的预期,对于vite也是停留在一知半解的程度上。最近想重新开始学习vite,但回顾之前的学习历程,感觉不太想继续之前的方式&…

Webpack HMR 原理解析

Hot Module Replacement(以下简称 HMR)是 webpack 发展至今引入的最令人兴奋的特性之一 ,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过新的模块替换老的模…

Webpack的HMR原理解析

Hot Module Replacement(以下简称 HMR)是 webpack 发展至今引入的最令人兴奋的特性之一 ,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过新的模块替换老的模…

Esbuild Bundler HMR

Esbuild 虽然 bundler 非常快,但是其没有提供 HMR 的能力,在开发过程中只能采用 live-reload 的方案,一有代码改动,页面就需要全量 reload ,这极大降低开发体验。为此添加 HMR 功能至关重要。 经过调研,社…

Vite HMR

传统webpack的hmr是使用webpack的HotModuleReplacementPlugin,而vite则是采用native ES Module的devServer。 初始化本地服务器加载并运行对应的plugin 最重要的一件事就是运行plugin,目前vite支持的plugin大体如下图所示 1、建立ViteDevServer服务器…

webpack HMR

HMR或者hot模式下,启动webpack会在浏览器与服务器之间会建立一个websocket连接,使得浏览器可以和服务端建立全双工通信;当应用程序的代码更新时,会要求HMR runtime检查更新,有更新时,在websoket连接中会返回…

webpack中的HMR(热更新)原理剖析

简介 Hot Module Replacement(以下简称 HMR)是 webpack 发展至今引入的最令人兴奋的特性之一 ,当你对代码进行修改并保存后,webpack 将对代码重新打包,并将新的模块发送到浏览器端,浏览器通过新的模块替换…

HMR(热替换)

HMR 即模块热替换(hot module replacement)的简称,它可以在应用运行的时候,不需要刷新页面,就可以直接替换、增删模块。webpack 可以通过配置 webpack.HotModuleReplacementPlugin 插件来开启全局的 HMR 能力&#xff…

面试官:说说Webpack的热更新是如何做到的?原理是什么?

一、是什么 HMR全称 Hot Module Replacement,可以理解为模块热替换,指在应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个应用 例如,我们在应用运行过程中修改了某个模块,通过自动刷新会导致整…

Webpack 热更新HMR 原理全解析

一、什么是 HMR HMR 全称 Hot Module Replacement,中文语境通常翻译为模块热更新,它能够在保持页面状态的情况下动态替换资源模块,提供丝滑顺畅的 Web 页面开发体验。 HMR 最初由 Webpack 设计实现,至今已几乎成为现代工程化工具…

curl.perform() pycurl.error: (23, 'Failed writing body (0 != 59)')

在使用python3.7编码时,引入pycurl模块和StringIO模块后,容易引起上述错误 导入StringIO模块的解决方案: 只有在python2中才能导入StringIO模块,直接 from StringIO import StringIO 即可 但是python3,STringIO和…

关于python的url处理

基本环境: python2.7 1 完整的url语法格式: 协议://用户名密码:子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数值#标识 2 urlparse模块对url的处理方法 urlparse模块对url的主要处理方法有:urljoin/urlsplit/urlunsplit/urlpar…

windows10+python3.7使用pip安装pycurl失败

使用pip install pycurl安装pycurl失败: python setup.py egg_info did not run successfully. 可以单独下载pycurl依赖文件然后安装 sArchived: Python Extension Packages for Windows - Christoph Gohlke (uci.edu) 选择Python对应版本的文件进行下载&#xff0…

Pycurl介绍

pycurl — A Python interface to the cURL library Pycurl包是一个libcurl的Python接口.pycurl已经成功的在Python2.2到Python2.5版编译测试过了. Libcurl是一个支持FTP, FTPS, HTTP, HTTPS, GOPHER, TELNET, DICT, FILE 和 LDAP的客户端URL传输库.libcurl也支持HTTPS认证,H…

[windows]python 安装pycurl

问题描述 pip install pycurl 报错 手动安装 下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/ 页面搜索: pycurl 下载对应版本的whl文件,我是windows环境 python3.8 所以下载pycurl-7.45.1-cp38-cp38-win32.whl 安装:…