手把手带你上手 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 源码的内容啦,如果你跟着学到这里,你已经成功的学会了调试源码。

相关推荐
祈澈菇凉1 小时前
Webpack的基本功能有哪些
前端·javascript·vue.js
小纯洁w1 小时前
Webpack 的 require.context 和 Vite 的 import.meta.glob 的详细介绍和使用
前端·webpack·node.js
想睡好2 小时前
css文本属性
前端·css
qianmoQ2 小时前
第三章:组件开发实战 - 第五节 - Tailwind CSS 响应式导航栏实现
前端·css
记得早睡~2 小时前
leetcode150-逆波兰表达式求值
javascript·算法·leetcode
zhoupenghui1682 小时前
golang时间相关函数总结
服务器·前端·golang·time
White graces2 小时前
正则表达式效验邮箱格式, 手机号格式, 密码长度
前端·spring boot·spring·正则表达式·java-ee·maven·intellij-idea
庸俗今天不摸鱼2 小时前
Canvas进阶-4、边界检测(流光,鼠标拖尾)
开发语言·前端·javascript·计算机外设
bubusa~>_<3 小时前
解决npm install 出现error,比如:ERR_SSL_CIPHER_OPERATION_FAILED
前端·npm·node.js
[廾匸]3 小时前
cesium视频投影
javascript·无人机·cesium·cesium.js·视频投影