看完这篇,面试再也不怕被问 Webpack 热更新,前端字节跳动面试题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
img

正文

为什么代码的改动保存会自动编译,重新打包?这一系列的重新检测编译依赖于 Webpack 的文件监听:在项目启动之后,Webpack 会通过 Compiler 类的 Run 方法开启编译构建过程,编译完成后,调用 Watch 方法监听文件变更,当文件发生变化,重新编译,编译完成之后继续监听。

image-20190925003133799

页面的访问需要依赖 Web 服务器,那要如何将 Webpack 编译打包之后的文件传递给 Web 服务器呢?这就要看 Webpack-dev-middleware了。 Webpack-dev-middleware 是一个封装器( wrapper ),它可以把 Webpack 处理过的文件发送到一个 Server(其中 Webpack-Dev-Server 就是内置了 Webpack-dev-middleware 和 Express 服务器)。上面有说到编译之后的文件会被写入到内存,而 Webpack-dev-middleware 插件通过 memory-fs 实现静态资源请求直接访问内存文件。

const webpack = require(‘webpack’);

const webpackConfig = require(‘./webpack.dev.conf’);

const compiler = webpack(webpackConfig);

debug(‘webpack编译完成’);

debug(‘将编译流通过webpack-dev-middleware’);

const devMiddleware = require(‘webpack-dev-middleware’)(compiler, {

// self-define options

});

复制代码

上面代码可以看到,Webpack 编译打包之后得到一个 Compilation ,并将 Compilation 传递到 Webpack-dev-middleware 插件中,Webpack-dev-middleware 可以通过 Compilation 调用 Webpack中 的 Watch 方法实时监控文件变化,并重新编译打包写入内存。

留意一下浏览器端,在 Network 中可以看到几个请求:

/__Webpack_hmr 请求返回的消息包含了首次 Hash 值,每次代码变动重新编译后,浏览器会发出 hash.hot-update.json、fileChunk.hash.hot-update.js 资源请求。

image-20190924112630734

点开查看 hash.hot-update.json 请求,返回的结果中,h 是一个 hash 值,用于下次文件热更新请求的前缀,c 表示当前要热更新的文件是 main1 。

image-20190924112716610

继续查看 fileChunk.hash.hot-update.js,返回的内容是使用 webpackHotUpdate 标识的 fileChunk 内容。

image-20190924113157232

那么 Webpack 服务器和浏览器端是怎么建立起通信的呢?这就是 Webpack-hot-middleware 插件的功劳了。 Webpack-hot-middleware 的 README.md 文档中有这样一段描述:

This module is only concerned with the mechanisms to connect a browser client to a Webpack server & receive updates.

Webpack-hot-middleware 插件的作用就是提供浏览器和 Webpack 服务器之间的通信机制、且在浏览器端接收 Webpack 服务器端的更新变化。

为了更好的理解这一段话,打开浏览器开发者调试工具,可以看到在 Webpack 打包好的 Js 中主要包含了以下几部分。下面截取关键部分进行说明:

  • Webpack-hot-middleware/client.js

源码中有这么一段配置,看到这里瞬间想到了在开发时浏览器的 Network 中总是有一个 __Webpack_hmr 的请求,点开查看会看到EventStream 事件流(服务器端事件流,服务器向浏览器推送消息,除了 websocket 全双工通道双向通信方式还有一种 Server-Sent Events 单向通道的通信方法,只能服务器端向浏览器端通过流信息的方式推送消息;页面可以通过 EventSource 实例接收服务器发送事件通知并触发 onmessage 事件),并且以 2s 的频率不停的更新消息内容,每行消息内容都有 ❤️ 的图标,没错这就是一个心跳请求。

var options = {

path: ‘/__Webpack_hmr’,

timeout: 20 * 1000,

overlay: true,

reload: false,

log: true,

warn: true,

name: ‘’,

autoConnect: true,

overlayStyles: {},

overlayWarnings: false,

ansiColors: {},

};

复制代码

继续向下查看 Client.js 代码,发现这完全就是一个只要浏览器支持就可以自发建立通信通道的客户端。

if (typeof window === ‘undefined’) {

// do nothing

} else if (typeof window.EventSource === ‘undefined’) {

// warning

} else {

if (options.autoConnect) {

// 建立通信连接

connect();

}

}

复制代码

在建立通信的过程中,浏览器端会初始化一个 EventSource 实例并通过 onmessage 事件监听消息。浏览器端在收到服务器发来的数据时,就会触发 onmessage 事件,可以通过定义 onmessage 的回调函数处理接收到的消息。

// 浏览器端建立连接

function EventSourceWrapper() {

var source;

var listeners = [];

// 初始化EventSource实例

source = new window.EventSource(options.path);

// 定义onmessage事件监听服务器端消息返回

source.onmessage = handleMessage;

function handleMessage(event) {

for (var i = 0; i < listeners.length; i++) {

listenersi;

}

}

return {

addMessageListener: function(fn) {

listeners.push(fn);

}

};

}

// 浏览器端建立通信通道,监听处理服务器端推送的消息

function connect() {

EventSourceWrapper().addMessageListener(handleMessage);

function handleMessage(event) {

try {

processMessage(JSON.parse(event.data));

} catch (ex) {

// handler exception

}

}

}

复制代码

Client.js 监听的消息有:

  • building/built:构建中,不会触发热更新; ​

  • sync:开始更新的流程。

在 processUpdate 方法中,处理一切异常/错误的方法都是直接更新整个页面即调用 window.location.reload(),首先调用 module.hot.check 方法检测是否有更新,然后进入 HotModuleReplacement.runtime 的 Check 阶段。

function processMessage(obj) {

switch (obj.action) {

case ‘building’:

// tell you rebuilding

break;

case ‘built’:

// tell you rebuilt in n ms

// fall through

case ‘sync’:

// 省略…

结尾

学习html5、css、javascript这些基础知识,学习的渠道很多,就不多说了,例如,一些其他的优秀博客。但是本人觉得看书也很必要,可以节省很多时间,常见的javascript的书,例如:javascript的高级程序设计,是每位前端工程师必不可少的一本书,边看边用,了解js的一些基本知识,基本上很全面了,如果有时间可以读一些,js性能相关的书籍,以及设计者模式,在实践中都会用的到。

html5

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
都会用的到。

[外链图片转存中…(img-OrGQwXpU-1713092684057)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-rUUKTlaq-1713092684057)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值