- Published on
vite-1.0简单介绍
- Authors
- Name
- 祝你好运
vite是通过使用ES Module来实现开发环境秒开,快速HMR的。这个ES Module说白了我们前端开发者应该每天都在用,因为我们都在用import,export来导入导出模块。不过如果你还是用的CommonJS的require,那就不是ES Module。
主思路
有了上面的思路,那就简单了,我们就是要把所有的代码,搞成ES Module,然后用一个Koa搭建一个HTTP服务器,然后当浏览器访问的时候,返回相应的代码,这就是主要的思路。
HMR (Hot Module Replace)
首先说什么是HMR,我们可以举一个React的例子,我们的React组件一般会对应到DOM上,当我们修改这个组件的时候,对应的DOM就会更新。那如果我们能做到,不刷新整个页面,只刷新那块更新的DOM,效率是不是大增?这个局部刷新,就是HMR。怎么样在我们修改组件的时候通知浏览器刷新?用WebSockets,然后在首页(比如index.html)注入client的代码,服务端启动WebSockets的服务端,然后监听文件改动。当文件有改动的时候,通知客户端,客户端拿到改动信息后,局部刷新页面就好了。当然这里还有一些别的辅助工具,后面详细讲。
功能扩展
说完上面的WebSockets,那就不得不提一下vite的plugin系统,本身vite就是一个koa服务器,我们知道koa上面是可以加很多中间件,然后这些中间件就是洋葱模型中的层。vite就有各种中间件,比如处理CSS的serverPluginCss.ts
,比如处理TypeScript
的serverPluginEsbuild.ts。比如处理静态文件的serverPluginServeStatic.ts
。
开发环境秒开
这里首先要强调是开发环境,生产环境vite是依赖Rollup的。但是第一次运行项目的时候,vite是需要一个优化的,它会用[Rollup]来把node_modules
下面那些CommonJS
的包打成ES Module
,放到node_modules/.vite_opt_cache/
下面。然后后续开发的时候,就直接从缓存加载这些package。例如React
就会被提前打包。
路径解析
上面提到React
会被提前打包,那当我们的文件中引入React
的时候,import React from 'react'
,具体会怎么引入文件呢?其实返回到浏览器之前,这些代码都被修改过了,这些修改大部分是在src/node/server/serverPluginModuleRewrite.ts
完成的。比如前面那个对React
的引入,会被修改为
import $viteCjsImport0_react from "/@modules/react.js";
const React = $viteCjsImport0_react;
那这个/@modules/react.js
又是如何对应到缓存里面的node_modules/.vite_opt_cache/
文件呢?这个是通过src/node/server/serverPluginModuleReresolve.ts
来完成的。
代码结构介绍
当我们要分析vite的源代码的时候,我们的注意力主要集中在src
上,更进一步,主要集中在src/node
上。src/client
里面就是HMR相关的,比如建立WebSockets相关的,还有当服务端监听到文件变更后,发给客户端,也就是浏览器,客户端相应的处理代码。在我们深入研究HMR之前,不需要看这些。
node
- build # 生产打包相关
- optimizer # 预打包,把node_modules下面的一部分包打成ES Module
- server # 我们启动的koa服务器相关,以及那些中间件
- cli.ts # 我们的vite命令行脚本
上面就是我们需要重点看的代码。
总结
其实从比较高的抽象层次来看的话,其实vite也很简单,就是koa服务器来来返回ES Module,外加各种优化。明白主要架构之后,后面再展开讲就不容易迷失在细节之中。