前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从零实现 vite(先导篇)

从零实现 vite(先导篇)

作者头像
lucifer210
发布2021-07-15 14:44:28
7250
发布2021-07-15 14:44:28
举报
文章被收录于专栏:脑洞前端脑洞前端

mono-vite

基本知识

假设我们有如下两个 JS 文件。

即两个 esm 的模块, 并且 main.mjs 依赖 utils.mjs。

如上代码可以被支持 ESM 的浏览器所识别,但并不意味着其可以直接被运行。比如我的代码依赖了 npm 包和一些相对路径,这些浏览器是无法识别的。

而 vite 则解决了这个问题。由于 vite 本质还是依赖了浏览器的特性,因此可以直接利用浏览器的诸如缓存的特点来提高性能。

除此之外, 每次修改文件,比如修改上面的 main.mjs 或者 utils.mjs 中的任意一个文件并不会导致“打包”全部文件。这是因为 vite 根本没有打包过程, 而是直接将修改过的文件热更新到浏览器的内存中。

比如,我修改了 main.js,那么就直接发送一个 http 去请求最新的 main.mjs 文件,而 utils.mjs 则可以继续使用浏览器缓存中的内容即可。

我画了一个简单的原理图给大家参考一下。

模块之间的关系如上图所示。并且这个时序指的是「更新一个文件之后的更新流程」

我将其分成了若干模块,它们分别是:

  • 浏览器。用于处理 ESM
  • 文件系统。用于存储源代码文件。
  • vite-server。响应浏览器,并返回内容。这些内容主要是最新的文件系统中的文件,除此外还有注入到 client 中的代码等。
  • hrm-sever。用于根据模块的依赖关系确定应该更新的模块,并触发相应的回调函数。
  • watcher。监听文件系统的变更,当文件内容发生变化的时候,通知 hmr-server。之后 hmr-server 再去通过 websocket 通知浏览器获取最新的模块(按需请求)。

如何确定需要更新的模块

我们可以根据 esm 的 import 关系生成一个依赖图。并将图中的所有点都放入一个哈希表中,key 可以是文件的请求路径,value 可以是模块本身,这样就可以根据请求路径在

O(1)

的时间获取到指定的节点。之后我们可以遍历依赖图,并依次发起浏览器的 http 请求获取最新内容,并触发回调函数。

如下图红色的模块被更新,我们通过

O(1)

时间获取到它,然后依次遍历虚线的两个模块,发起请求获取其最新模块内容,最后触发注册到这「三个」模块上的回调函数即可。

❝回调函数通过 module.hot.accept 注册,具体参考 hmr 相关文档。 ❞

一个更复杂的例子:

之后我会根据这个原理图带大家一步步实现一个 mono-vite(等西法有时间的)。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 脑洞前端 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • mono-vite
    • 基本知识
      • 如何确定需要更新的模块
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档