从零读 Vite 4.0 源码(一)———— vite 诞生

本系列文章试图带给你一些信息:

  • vite 的设计理念
  • vite 核心功能(预构建、HMR)的实现原理
  • 以 vite 为例,说明如何阅读源码

前置说明:

  • 基于 vite 4.4.9 版本阅读

vite 诞生之前的世界

要理解 vite 先进的设计理念,需要先回顾一下打包工具的历史。

首先,先思考一个问题:我们为什么需要使用打包工具呢?

在没有打包工具之前,在浏览器中运行 javascript, 只能通过引用脚本的方式。这种方式带来了作用域,文件大小,可读性和可维护性等一系列问题。

随后出现的 IIFE,用来解决项目中的作用域问题。这是诞生了 gulp, grunt 等工具,用来基于 IIFE 拼接所有项目文件。但对 treeshaking 和脚本重用依然很不友好。

再之后,node.js 带来了模块化的理念,commonjs 引入了 require 机制,允许在文件中加载模块。更加优雅的解决了作用域的问题。但浏览器不支持模块,因此诞生了 Browserify 等工具,允许我们编写的 commonjs 模块运行在浏览器上。

但当时尚未存在一款开箱即用的打包工具,可以自动构建并分析依赖,为开发者提供更方便的开发体验。这时 webpack 诞生了,webpack 不仅可以将模块化的代码打包成可在浏览器中运行的文件外,还提供了代码拆分等丰富的功能,以及繁荣的生态系统。

不可否认 webpack 是一款非常优秀的打包工具,也极大的改善了开发体验。但随着项目原来越庞大,构建工具开始遇到性能瓶颈,文件修改后需要数秒才能看到结果,这无疑损伤了开发者的体验。

但还记得我们最一开始的痛点么?正是因为浏览器不支持模块化而带来了这一系列的问题。

现代浏览器已逐步支持原生 ES 模块,也就是说,我们或许不再需要再使用工具将我们的源码串联成可以在浏览器中运行的文件。而是无需构建整个应用,直接让我们的脚本运行在浏览器中!

vite 正是基于这一理念的新打包工具。由于不需要在每次构建的时候打包所有文件,因此它提供了非常快速的开发体验。

你的 vite

既然我们现在知道 vite 是基于浏览器支持原生 ES 模块这一理念设计的,那不妨想一想,如果是你,会如何设计呢?

首先,可以利用浏览器原生 ES 模块的特性,我们不再需要将文件打包,浏览器原生的 ES 模块会自动请求源码脚本,并将脚本运行在浏览器上。

由于源码本身并非是 javascript 文件,如 JSX, vue等,所以你的 vite 需要针对被请求的源码进行转换。

其次,当文件发生改变时,我们需要 vite 能监听到变化并进行增量编译,所以你的 vite 需要在本地启动一个 server,并能够监听文件变化并处理。

最后,考虑下性能,我们希望每次编译后的源码若无变化,则使用缓存。这一点浏览器就可以为我们做,源码会根据请求头中的 if-not-match 进行协商缓存,从而避免重复处理一份未变化的源码。所以你的 vite 只需要关注下请求头的设置即可。

让我们先来开始思考一下如何实现以上的一个功能吧。

Tobe continue..


86 Words

2023-09-22 06:47 +0000