当前位置:首页 > 生活百科

webpack热更新是什么(webpack热更新原理)

栏目:生活百科日期:2025-04-30浏览:0

背景

传统开发页面,每次更新的时候需要我们手动刷新浏览器才会更新。自从构建工具横空出世。我们可以通过热更新的方式来进行更新。通称HMR(hot module replacement),也就是模块热替换,当你每次需要更新代码的时候,不在需要手动刷新即可实现效果预览。

前置知识

探究热更新是怎么实现之前,我们需要知道几样东西

sockjswebpack.HotModuleReplacementPluginmemory-fswebpack-dev-middlewarewebpack一些知识和一些底层知识,否则你估计会看不懂,并且属于懵逼状态,对于一些东西都给出了链接Compiler事件流

memory-fs

内存文件系统,webpack默认生成的文件会丢到内存中,并不会直接写入硬盘

webpack.HotModuleReplacementPlugin

中文文档

英文文档

这个是HMR实现核心,由webpack内部所提供的一个插件,该插件会提供一些方法,用于检查变更,并告诉你每次变更所生成的文件hash

sockjs

用于发送socket请求,通知浏览器进行更改

webpack-dev-middleware

webpack-dev-middleware会接收一个webpack所返回的一个compiler对象,然后调用compiler.watch监听文件更改,

我们知道webpack热更新的时候,并不会写入硬盘中,这是因为默认的情况下是写入内存的,因为内存的读取速度比硬盘会快很多,我们可以通过devServer.writeToDisk来修改

if (options.writeToDisk) {    // 写入硬盘} else {    // 写入内存,并设置内存中的路径为当前路径    const memoryFs = new MemoryFs()}复制代码

这样我们就可以知道文件是否更改,并且把文件存在了内存中,现在在回到webpack-dev-server

HMR是怎么实现的

这里用webpack-dev-server进行举例,所有热更新原理基本类似。手写我们实现一个简单的webpack配置文件。

const path = require('path')const webpack = require('webpack')const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = {    entry: './src/index.js',    output: {        path: path.resolve(__dirname, 'dist'),        filename: 'main.js'    },    devServer: {        host: 'localhost',        contentBase: path.resolve(__dirname, 'src')        port: 8080,        hot: true,        open: true    },    plugins: &[        new webpack.HotModuleReplacementPlugin(),        new HtmlWebpackPlugin({            template: './src/pages/index.html',            filename: 'index.html'        })    ]}复制代码

简单实现

这是一个简单的流程图,不涉及任何复杂逻辑,这图中我们需要关注几个问题

为什么需要启动为什么需要添加webpack.HotModuleReplacementPluginwebpack-dev-server怎么知道文件发生了变化如何实现更新

现在我们有了上面的问题,来逐个去看下

为什么需要webpack.HotModuleReplacementPlugin

这个是webpack官方所提供的插件,该插件提供了一些方法,当我们启动的时候webpack会给每个文件注入moudle一个对象,这个对象里面有个module.hot对象,具体可以参考 中文文档 ,并且webpack每次重新构建的时候会生成一个hash,当我们把devServer.writeToDisk设置为true的时候,每次更改还会生成这2个文件。

hot-update.js是每次需要更新的文件hot-update.json下次更新需要生成的hash

&[id].&[fullhash].hot-update.js&[runtime].&[fullhash].hot-update.json复制代码

webpack-dev-server怎么知道文件发生了变化

这个问题比较简单,webpack-dev-server启动的时候,初始化了express,并且把expres传递给了webpack-dev-middleware,webpack-dev-middleware也是webpack团队出品,devServer几乎所有api都是通过这个库去实现的。

webpack构建的时候会返回一个compiler对象,该对象会提供一个watch方法用来监听文件更改,而webpack-dev-middleware就是通过这种方法监听文件更改,
webpack.HotModuleReplacementPlugin也是一样的操作。并且每次重新构建的时候webpack-dev-server都会监听compiler的compile、invalid、done方法,会通知socket服务用于是否展示overlay(遮罩层)。

compile 在compilation生成之前,compilation是webpack每次重新编译所返回的一个对象invalid 编译失败done 编译成功如何实现更新

webpack-dev-server在启动的时候还会给entry添加2个文件

webpack-dev-server/clinet/index.jswebpack/hot/devServer.js // 如果设置了hotonly会注入webpack/hot/only-dev-server复制代码

现在我们知道了每次构建所产生的hash,和产生的文件,但这时候还没办法热更新。我们可以记录每次构建所生成的hash,用于判断和当前的hash是否匹配,从而实现热更新,并且通知浏览器进行更新。

webpack-dev-server/client/index.js负责每次更新的状态,当状态为ok和warinings的时候会执行一个reloadApp方法,该方法会emit一个webpackHotUpdate事件,并把变更的文件hash传递出去,然后webpack/hot/devServer.js负责监听这个事件,当监听到该事件的时候,保存该文件hash,并且判断hash是否已更新并且module.hot.status为idle的时候,执行一个check方法,check会拿到一个需要更新的模块,如果有需要更新,则调用location.reload()方法,进行更新。

if (module.hot) {var lastHash;var upToDate = function upToDate() {return lastHash.indexOf(__webpack_hash__) &>= 0;};var log = require("./log");var check = function check() {module.hot.check(true).then(function(updatedModules) {if (!updatedModules) {log("warning", "&[HMR] Cannot find update. Need to do a full reload!");log("warning","&[HMR] (Probably because of restarting the webpack-dev-server)");window.location.reload();return;}if (!upToDate()) {check();}require("./log-apply-result")(updatedModules, updatedModules);if (upToDate()) {log("info", "&[HMR] App is up to date.");}}).catch(function(err) {var status = module.hot.status();if (&["abort", "fail"].indexOf(status) &>= 0) {log("warning","&[HMR] Cannot apply update. Need to do a full reload!");log("warning", "&[HMR] " + log.formatError(err));window.location.reload();} else {log("warning", "&[HMR] Update failed: " + log.formatError(err));}});};var hotEmitter = require("./emitter");hotEmitter.on("webpackHotUpdate", function(currentHash) {lastHash = currentHash;if (!upToDate() &&&& module.hot.status() === "idle") {log("info", "&[HMR] Checking for updates on the server...");check();}});log("info", "&[HMR] Waiting for update signal from WDS...");} else {throw new Error("&[HMR] Hot Module Replacement is disabled.");}复制代码

现在我们已经大概了解了热更新的过程。

“webpack热更新是什么(webpack热更新原理)” 的相关文章

修复驱动器是什么意思(修复驱动器的意思解释)

1.开启MyASUS后,点选左侧的系统诊断项目,在任何一项(或多项)检测点选[开始检查]。2.检查完毕后,点选[上一次结果],下拉至页面的底部,点选[创建系统修...

cpb防晒霜到底好不好用(这款防晒霜让你美白防晒一步到

cpb防晒乳霜专柜多少钱?好用吗?cpb家的防晒乳霜全新升级——cpb御龄防晒乳霜,50的高倍防晒,而且还可以抵御肌肤衰老,具有润色效果,可以让肌肤更加璀璨,下...

共享充电宝有哪些品牌,共享充电宝十大排名

我们是电佳共享充电宝的总部。电佳是我们公司自主品牌,自主研发,自主生产,自主创新。0加盟费0代理费0抽成,一台总部直签,诚招全国代理。100%分润,独立后台实时...

京东Q3全品类健康增长 带动用户平均购物频次提升23%

11月18日,京东集团(纳斯达克股票代码:JD;港交所股票代号:9618)发布2021年第三季度财报。2021年第三季度,京东集团净收入为2187亿元人民币(约...

公司注册资金是真的吗,注册公司流程及费用

相信找过工作的人都知道在查一家公司的真实情况时,都会查到一家的注册资金;小编以前以为一家公司的注册资金很高那么这个公司规模一定很大,但是到公司了解之后却发现公司...

wifi无线模式选哪个好(提高自家wifi网速的方法)

一、WiFi模块是什么?有什么作用?WiFi模块属于物理网络传输层,具有内置的无线网络协议IEEE802.11b.gn协议栈和TCP/IP协议栈。串行端口或TT...

photoshop图文教程(ps抠图教程详细步骤)

如何给人美白?我相信每个人的皮肤都是或多或少,即使是明星也是,那么为什么他们的海报都是如此干净?事实上,通过PS美化画面,以下小系列需要大家看如何使用PS给人类...

中国婴儿品牌排行榜(宝妈们公认最好的四个婴幼儿用品知

婴儿用品是0-1岁宝宝这类特殊群体的专业用品,特殊的生理、心理需求对婴儿用品有着极高的要求。因此妈妈们对婴儿用品的选择要求十分严格。什么品牌的婴儿用品比较好?我...

nginx负载均衡策略有哪些( 解锁nginx负载均衡配置及其

多用户访问出现问题开发时,一个项目只有少数几个人进行访问,此时使用tomcat能够很好地进行访问,但访问量大的时候服务器便不能很好的处理,有的小伙伴可能不知道什...

word文档结构图设置修改(word文档基础教程)

组织结构图在我们的日常工作中经常被用到,但是很多朋友不会做,或是做一个组织结构图需要两三个小时,那也太浪费时间了吧!其实,利用Word就能制作组织结构图,而且还...