在了解 Vite 如何利用“原生 ESM 加载”之前,我们先回顾一下浏览器处理模块的基本流程:
浏览器加载入口模块
在你的 index.html
中,通常会有这样一行:
<script type="module" src="/main.js"></script>
浏览器看到 type="module"
就会用 ES Module 规范来处理它:先发一个 HTTP GET 请求拿 /main.js
,然后解析其中的 import
语句,依次再去请求其他模块。
HTTP 请求到来时被 Vite Dev Server 拦截
当浏览器请求任何以 .js
、.ts
、.vue
等结尾的资源时,这些请求都会打到正在运行的 Vite 开发服务器上。Vite 不会像传统打包器那样先把所有代码打包好再发,而是在收到请求的那一刻:
import vue from 'vue'
)?/node_modules/.vite/deps/xxx.js?v=hash
这样一个真实可请求的 URL (vite.dev)。浏览器执行并再次发起新的模块请求
浏览器收到编译后的模块代码后会立即执行,同时解析里面的 import
,产生新的 HTTP 请求,这些请求依旧被 Vite 拦截、解析、编译,然后返回。如此循环,直到所有模块都加载完毕。
import 'vue'
这样的路径,映射为浏览器能直接请求到的文件 URL(通常带有版本哈希以支持缓存)。通过这种方式,Vite 借助浏览器自身的 ESM 能力,实现了近乎“零启动”时间的开发体验,同时保留了对 TS/JSX、框架组件等所有高级特性的支持。