「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战」。
1. Vite 对 TypeScript 的支持
Vite 默认支持对 TypeScript 的处理吗?我们可以测试一下。在 src 文件夹下新建 ts 文件夹,在 ts 文件夹下新建 mul.ts 文件,内容如下:
export default function(num1: number, num2: number): number {
return num1 * num2;
}
然后我们在 src/main.js 文件中导入这个 ts 文件,之后使用里面的这个乘法函数:
保存文件后,我们再来看浏览器中的效果:
可以看到,控制台中成功打印了 10 乘 20 的结果,可见,Vite 默认情况下就支持 ts 代码。
Vite 对 TypeScript 是原生支持的,它会直接使用 esbuild 来完成编译,将 TypeScript 转译到 JavaScript,我们只需要直接导入 ts 文件即可。
2. Vite 默认支持 TypeScript 的内部原理
Vite 到底是如何做到对 ts 的支持,以及对 less 等预处理器语言的支持的呢?
我们先来看之前的项目启动之后,浏览器中的请求信息:
你会发现,浏览器在向 Vite 搭建的本地服务器请求时,请求的还是 mul.ts 这个 ts 文件、title.less 这个 less 文件。
事实上,Vite 会搭建一个本地服务器(不同于 Webpack 中 webpack-dev-server 使用的是 express 搭建的本地服务器,在 Vite 1 中使用的是 koa 搭建的本地服务器,而在 Vite 2 中使用的是 Connect 库搭建的本地服务器(官方文档中也有说明:cn.vitejs.dev/guide/migra… ,这个 Connect 库用来做基本的服务器还是很不错的))。
在我们这里,浏览器在向这个服务器请求的可不是 mul.js 文件,而是 mul.ts 文件,同样地,浏览器还请求了 title.less 文件,但是,less 文件和 ts 文件显然不能直接交给浏览器解析,因为浏览器解析不了这两种文件类型的代码。那么,Vite 内部做了什么事情呢?Vite 内部会先将这两个文件(mul.ts、title.less)中的代码进行转化,转化为 ES6 的 js 代码(less/css 代码也会转成 js 代码,之后会通过 js 将样式代码放到 <style> 元素中再注入到 html 文件中去),然后这两个文件的名字和后缀依然不变。那么,当浏览器请求这两个文件时,Vite 内部会对请求进行拦截,然后将请求转发(这也是使用 Connect 库做服务器的原因,因为 Connect 非常容易做请求转发。个人猜测 Vite 1 到 Vite 2,服务器从 koa 换成 Connect 是因为除了考虑到要搭建一个本地服务,内部更多的是要做转发的工作,即本来是请求文件 a1,之后会转发为去请求文件 a2,最后返回的是文件 a2),最后请求到的其实是内部已经转换成了 ES6 的 JS 代码的文件,只不过文件名和文件后缀依然没变。所以浏览器最终执行的是这些 ES6 的 js 代码,之后在页面上显示对应的效果,控制台打印对应的结果。以上,就是 Vite 的原理(Vite 在开发阶段,本质上就是一个本地服务器,它会帮我们编译很多代码,比如 ts 代码、less 代码、.vue 文件的代码,对这些代码进行转化,转化为 ES6 的 js 代码,之后浏览器请求这些文件时,它会做转发,转发到去请求这些文件转化后的代码,最后返回这些转化后的 ES6 的 js 代码,让浏览器去解析、执行,展示对应的效果)。
如果我们查看浏览器中的请求,会发现请求的依然是 .ts、.less 的文件。这是因为 Vite 中的服务器 Connect 会对我们的请求进行转发,获取 ts、less 编译后的代码,返回给浏览器,浏览器可以直接进行解析。
在浏览器的 Network 面板下点开 mul.ts 文件,点击 Response 标签,你会发现里面是 js 的代码,而且还是 ES6 的 js 代码:
同样的,title.less 中也都是 js 代码:
title.less 中的 js 代码做的事情就是把 less 文件中的样式以 <style> 标签的形式插入到 html 中去(跟 style-loader 做的事情类似,只不过 Vite 是把代码转换成了 ESM 的方式去实现的样式插入)。
以上,就是关于 Vite 服务器内部原理的说明。