手把手带你上手 Vite 源码调试

一位前端同学告诉我,他在使用 vite 构建项目后,并没有删除原来的 dist 目录。这让我感到困惑,因为根据我了解,每次使用 vite 进行构建时,都应该清理掉 dist 目录。为了搞清楚这个问题,我觉得阅读 vite 的源代码是非常必要的。

所以这篇文章的目的,也是记录自己学习 vite 源码的过程,如果有什么错误的地方欢迎评论指正。

从官方文档入手

你肯定和我一样,当看到这个问题的时候,第一时间想到的就是是不是配置的问题,直接打开 vite 相关的配置文档。

构建配置文档:cn.vitejs.dev/config/buil...

vite 的官方文档当中,可以找到下面相关的一项配置:

vite 的官网配置当中,可以看到 build.emptyOutDir 这个配置项,使用 vite 打包项目的时候 dist 目录默认情况是在 root 目录下,所以 vite 是会在每次执行打包的时候是会将旧的 dist 目录进行删除的。

在创建一个新项目然后打包验证之后,我还是决定自己查看一下源码,一来是加强自己阅读源码的能力,再就是想看看 vite 的源码是怎么写的。

阅读源码前的准备

当然你既然能够阅读这篇文章,说明 node/npm 这样的工具,你已经再熟悉不过了 。 这里假设你已经对 pnpm 和 monorepo 已经有了基础的了解,不过不了解也没关系,用到它们的时候我会进行说明和一些学习文档。

pnpm-workspce 学习文档: pnpm.io/zh/workspac...

vite 源码仓库地址:github.com/vitejs/vite

我们使用 git 将 vite 的源码 clone 到我们自己的电脑上,命令如下:

bash 复制代码
git clone git@github.com:vitejs/vite.git

当然,如果你使用 git clone 的速度非常的慢,也可以选择直接下载压缩包或者其他方案。

克隆完毕,获得的 vite 源码如下所示:

通过整个工程的目录结构,我们可以得出 vite 是采用 pnpm workspace 的方式来管理整个项目的,接着查看 pnpm-workspace.yaml 文件。

yaml 复制代码
packages:
  - 'packages/*'
  - 'playground/**'

从上面的 yaml 文件当中可以得到,vite 源码当中,分开了源码的包(即 packages/*) 和示例源码(即 playgorund/**)。

调试源码

经过上面的步骤,我们已经得到了 vite 的源码,接下来我们需要找到 vite 源码的入口。 首先先执行 pnpm install ,将整个工程所有的依赖都安装好。

注意这里安装依赖只能够使用 pnpm ,因为在 npm script 当中使用到了 script 的生命周期钩子对包管理器进行了相关限制,关于怎么限制使用包管理器,这个可以去查看 only-allow 这个包相关的文档,其原理也是非常简单,以后有机会再进行介绍。

构建 vite

通过项目的 package.josn 文件,项目里面有 dev 命令能够让让我们去调试 vite 的源码,直接在项目的根目录下执行 pnpm run dev ,能够在终端当中看到如下输出

到这里,我们已经成功的将 vite 的源码以开发的成功的跑了起来。

vite 源码当中的 pnpm run dev 命令解析

当我们执行 vite 源码工程当中的 dev 命令,其实执行的是下面这条命令。

bash 复制代码
pnpm -r --parallel --filter='./packages/*' run dev

上面这条命令的意思是让 pnpm 并行在 ./packges/* 下面的各个子工程当中执行 dev 命令。

vite 的源码所处位置就是 packages/vite 这个工程当中。如果你使用过 node 开发过 cli 工具,那么对 vite 源码所在的工程目录结构一定非常熟悉。

通过 package.json 当中的 bin 字段,可以知道当我们执行在命令行执行 vite 命令的时候,这个命令真正执行的是 bin/vite.js,也就是对应 vite 源码目录如下指示的文件,这里就是 vite 源码的入口位置了。

再回过头去看我们最刚开始执行的 pnpm run dev 命令对应的执行了 vite 这个工程下的 dev 命令。

可以看到当执行 dev 的时候,会先将之前打包构建出来的 vite 进行删除,然后再以监听文件变化的方式调用 rollupvite 进行源码构建。

关于对 rollup 的使用,可以参考 rollup 官方文档进行学习。 rollup 官方文档:cn.rollupjs.org/

调试 vite 的源码

因为整个 vite 是采用 monorepo 的方式进行管理的,可以非常方便不同子工程相互之间的依赖和引用。

通过项目的依赖可以看到,项目依赖的 vite 就是当前工作空间的当中一个名叫 vite 的子工程,也就是 vite 的源码工程。

接下来我们切换到 playground 目录下,随便选择一个工程,这里我直接选第一个 alias 工程,执行 pnpm run dev,可以在控制台下面的输出信息。

到这里已经同时运行了一个 vite 源码工程和一个示例项目,下面就是开始对 vite 的源码进行调试了。

回到上面 bin/vite.js ,大概在第 43 行的位置,可以看到定义了一个 start() 的函数,这个函数就是将打包好的 vite cli 相关的代码进行执行,其对应的打包之前的源码就是 src/node/clit.ts

带着最刚开始的问题,build 生成产物之前不会把原来的 dist 目录删掉吗?

当我们执行 vite build 的时候,其最终执行的是 src/node/cli.ts 大概第 272 行到 295 行代码相关的内容,也就是调用 build 函数。

我的跟着源码点到 build 函数当中去看,可以看到调用 prepareOutDir 这个函数,前面的判断我们可以自己增加 console.log 语句查看,当然官方文档当中已经告诉我们 options.write 这个配置默认情况下是 true

我们在 prepareOutDir 函数当中增加一些调试用的控制台打印代码。

然后我们在 playground/alias 这个工程当中,执行 pnpm run build

可以看到,我们添加的调试信息已经成功加到源码当中去了。

接着阅读下面的源码,就可以找到答案了,当 outDirroot 目录下,并且 emptOutDir 的值与 false 不相等(也就是 emptyOutDir !== false 条件成立)的时候,就会把原来的 dist 目录删掉。

所以 vite 官方文档上关于 build.emptyOutDir 默认值的描述,应该是 null

所以默认情况下,vite 是会在新的打包输出之前将旧的目录给清理掉的,至于那位前端同学使用的 vite 为啥会有这个问题,他说他使用的是 vite 2,我猜大概了是 vite 的bug。

上面就是关于上手调试 vite 源码的内容啦,如果你跟着学到这里,你已经成功的学会了调试源码。

相关推荐
帅比九日19 分钟前
【HarmonyOS NEXT】实战——登录页面
前端·学习·华为·harmonyos
摇光9330 分钟前
promise
前端·面试·promise
hummhumm41 分钟前
第 12 章 - Go语言 方法
java·开发语言·javascript·后端·python·sql·golang
hummhumm41 分钟前
第 8 章 - Go语言 数组与切片
java·开发语言·javascript·python·sql·golang·database
麻花20131 小时前
WPF学习之路,控件的只读、是否可以、是否可见属性控制
服务器·前端·学习
.5481 小时前
提取双栏pdf的文字时 输出文件顺序混乱
前端·pdf
jyl_sh1 小时前
WebKit(适用2024年11月份版本)
前端·浏览器·客户端·webkit
狼叔1 小时前
前端潮流KK:科技达人与多面手,如何找到自己的乐趣?-浪说回顾
前端
zhanghaisong_20152 小时前
Caused by: org.attoparser.ParseException:
前端·javascript·html·thymeleaf
Eric_见嘉2 小时前
真的能无限试(白)用(嫖)cursor 吗?
前端·visual studio code