深入了解webpack原理(上)

1,383 阅读3分钟

一、认识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的工作流程

  1. webpack配置参数,合并从 shell传入和 webpack.config.js 文件里配置的参数,生成出最后的配置结果
  2. 注册所有配置的插件,好让插件监听 webpack 构建生命周期的事件节点,以做出对应的反应。
  3. 从配置的entry入口文件开始解析文件构建 AST 语法树,找出每个文件所依赖的文件,递归下去
  4. 在解析文件递归的过程中根据文件类型和 loader 配置找出合适的 laoder 用来对文件进行转换
  5. 递归完后得到每个文件的最终结果,根据 entry 配置生成代码块 chunk
  6. 输出所有 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的热更新原理

  1. webpack编译期,为需要热更新的 entry 注入热更新代码 (EventSource通信)
  2. 页面首次打开后,服务端与客户端通过 EventSource 建立通信渠道,把下一次的hash返回给前端
  3. 修改页面代码后,webpack监听到文件修改后,开始编译,编译完成后,发送build消息给客户端
  4. 客户端获取到hash,成功后客户端构造 hot-update.js script链接,然后插入到主文档中
  5. hot-update.js 插入成功后,执行 hotAPI 的 createRecord 和 reload 方法,获取到 Vue 组件的 render方法,重新render组件,继而实现UI无刷新更新