一、认识webpack
1、 什么是webpack?(摘自官网)
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
2、module、chunk 和 bundle的区别
module、chunk和bundle实质上是同一份逻辑代码在不同的三种转换场景下的状态名称。具体区别:
- module: 指的是各个源码文件,webpack看来一切皆模块
- chunk: 是多个模块合并成,包括的类型有:
- webpack配置中入口文件entry是chunk
- 入口文件以及它的依赖文件通过动态加载import()/require.ensure()出来的模块是chunk
- 通过SplitChunks抽取出的公有代码 也是chunk
- bundle: 最终的输出文件,也可以经过打包压缩和编译的源文件,可以直接在浏览器上运行
3、一张图理解webpack
结合下图,更好去理解module、chunk和bundle三者的关系
二、webpack的工作流程
- webpack配置参数,合并从 shell传入和 webpack.config.js 文件里配置的参数,生成出最后的配置结果
- 注册所有配置的插件,好让插件监听 webpack 构建生命周期的事件节点,以做出对应的反应。
- 从配置的entry入口文件开始解析文件构建 AST 语法树,找出每个文件所依赖的文件,递归下去
- 在解析文件递归的过程中根据文件类型和 loader 配置找出合适的 laoder 用来对文件进行转换
- 递归完后得到每个文件的最终结果,根据 entry 配置生成代码块 chunk
- 输出所有 chunk 到文件系统
三、认识EventSource
由于webpack热加载中利用了EventSource来进行通信,所以先一起来认识下 EventSource。
1、什么是 EventSource?
- MDN上的定义: EventSource 是服务器推送的一个网络事件接口。一个EventSource实例会对HTTP服务开启一个持久化的连接,以text/event-stream 格式发送事件, 会一直保持开启直到被要求关闭
- 通俗理解:是基于 Http 的单向通信,实现了服务端推送消息给客户端的功能,而客户端无法向服务端推送消息。
2、 EventSource 和 websocket 的区别?
- (1)WebSocket基于TCP协议,EventSource基于http协议。
- (2)EventSource是单向通信,而websocket是双向通信。
- (3)EventSource只能发送文本,而websocket支持发送二进制数据。
- (4)在实现上EventSource比websocket更简单。
- (5)EventSource有自动重连接(不借助第三方)以及发送随机事件的能力。
- (6)websocket的资源占用过大EventSource更轻量。
- (7)websocket可以跨域,EventSource基于http跨域需要服务端设置请求头。
四、webpack的热更新原理
- webpack编译期,为需要热更新的 entry 注入热更新代码 (EventSource通信)
- 页面首次打开后,服务端与客户端通过 EventSource 建立通信渠道,把下一次的hash返回给前端
- 修改页面代码后,webpack监听到文件修改后,开始编译,编译完成后,发送build消息给客户端
- 客户端获取到hash,成功后客户端构造 hot-update.js script链接,然后插入到主文档中
- hot-update.js 插入成功后,执行 hotAPI 的 createRecord 和 reload 方法,获取到 Vue 组件的 render方法,重新render组件,继而实现UI无刷新更新