Vite 对 TypeScript 的支持及其原理

4,430 阅读4分钟

「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战」。

1. ViteTypeScript 的支持

Vite 默认支持对 TypeScript 的处理吗?我们可以测试一下。在 src 文件夹下新建 ts 文件夹,在 ts 文件夹下新建 mul.ts 文件,内容如下:

export default function(num1: number, num2: number): number {
  return num1 * num2;
}

然后我们在 src/main.js 文件中导入这个 ts 文件,之后使用里面的这个乘法函数:

image-20211219174217187

保存文件后,我们再来看浏览器中的效果:

image-20211219174314583

可以看到,控制台中成功打印了 1020 的结果,可见,Vite 默认情况下就支持 ts 代码。

ViteTypeScript 是原生支持的,它会直接使用 esbuild 来完成编译,将 TypeScript 转译到 JavaScript,我们只需要直接导入 ts 文件即可。

2. Vite 默认支持 TypeScript 的内部原理

Vite 到底是如何做到对 ts 的支持,以及对 less 等预处理器语言的支持的呢?

我们先来看之前的项目启动之后,浏览器中的请求信息:

image-20211219174954955

你会发现,浏览器在向 Vite 搭建的本地服务器请求时,请求的还是 mul.ts 这个 ts 文件、title.less 这个 less 文件。

事实上,Vite 会搭建一个本地服务器(不同于 Webpackwebpack-dev-server 使用的是 express 搭建的本地服务器,在 Vite 1 中使用的是 koa 搭建的本地服务器,而在 Vite 2 中使用的是 Connect 库搭建的本地服务器(官方文档中也有说明:cn.vitejs.dev/guide/migra… ,这个 Connect 库用来做基本的服务器还是很不错的))。

image-20211219205334604

image-20211219205727991

在我们这里,浏览器在向这个服务器请求的可不是 mul.js 文件,而是 mul.ts 文件,同样地,浏览器还请求了 title.less 文件,但是,less 文件和 ts 文件显然不能直接交给浏览器解析,因为浏览器解析不了这两种文件类型的代码。那么,Vite 内部做了什么事情呢?Vite 内部会先将这两个文件(mul.tstitle.less)中的代码进行转化,转化为 ES6js 代码(less/css 代码也会转成 js 代码,之后会通过 js 将样式代码放到 <style> 元素中再注入到 html 文件中去),然后这两个文件的名字和后缀依然不变。那么,当浏览器请求这两个文件时,Vite 内部会对请求进行拦截,然后将请求转发(这也是使用 Connect 库做服务器的原因,因为 Connect 非常容易做请求转发。个人猜测 Vite 1Vite 2,服务器从 koa 换成 Connect 是因为除了考虑到要搭建一个本地服务,内部更多的是要做转发的工作,即本来是请求文件 a1,之后会转发为去请求文件 a2,最后返回的是文件 a2),最后请求到的其实是内部已经转换成了 ES6JS 代码的文件,只不过文件名和文件后缀依然没变。所以浏览器最终执行的是这些 ES6js 代码,之后在页面上显示对应的效果,控制台打印对应的结果。以上,就是 Vite 的原理(Vite 在开发阶段,本质上就是一个本地服务器,它会帮我们编译很多代码,比如 ts 代码、less 代码、.vue 文件的代码,对这些代码进行转化,转化为 ES6js 代码,之后浏览器请求这些文件时,它会做转发,转发到去请求这些文件转化后的代码,最后返回这些转化后的 ES6js 代码,让浏览器去解析、执行,展示对应的效果)。

vite的服务器原理

如果我们查看浏览器中的请求,会发现请求的依然是 .ts.less 的文件。这是因为 Vite 中的服务器 Connect 会对我们的请求进行转发,获取 tsless 编译后的代码,返回给浏览器,浏览器可以直接进行解析。

在浏览器的 Network 面板下点开 mul.ts 文件,点击 Response 标签,你会发现里面是 js 的代码,而且还是 ES6js 代码:

image-20211219204446830

同样的,title.less 中也都是 js 代码:

image-20211219204637000

title.less 中的 js 代码做的事情就是把 less 文件中的样式以 <style> 标签的形式插入到 html 中去(跟 style-loader 做的事情类似,只不过 Vite 是把代码转换成了 ESM 的方式去实现的样式插入)。

以上,就是关于 Vite 服务器内部原理的说明。