工作原理: - type="module" 浏览器中ES Module原生native支持。 如果浏览器支持type="module" ,我i们可以使用es6模块化的方式编写。浏览器会把我们需要导入的文件再发一次http请求,再发到服务器上。 开发阶段不需要打包
- 第三方依赖预打包
- 启动一个开发服务器处理资源请求
一图详解vite原理: 
浏览器做的什么事啊
宿主文件index.html<script type="module" src="/src/main.js"></script> 浏览器获取到宿主文件中的资源后,发现还要再去请求main.js文件。会再向服务端发送一次main.js的资源请求。 
main.js在main中,可以发现,浏览器又再次发起对vue.js?v=d253a66c、App.vue?t=1637479953836两个文件的资源请求。 服务器会将App.vue中的内容进行编译然后返回给浏览器,下图可以看出logo图片和文字都被编译成_hoisted_ 的静态节点。 
从请求头中,也可以看出sfc文件已经变成浏览器可以识别的js文件(app.vue文件中要存在script内容才会编译成js)。对于浏览器来说,执行的就是一段js代码。 
其他裸模块如果vue依赖中还存在其他依赖的话,浏览器依旧会再次发起资源请求,获取相应资源。
了解一下预打包对于第三方依赖(裸模块)的加载,vite对其提前做好打包工作,将其放到node_modules/.vite下。当启动项目的时候,直接从该路径下下载文件。 
通过上图,可以看到再裸模块的引入时,路径发生了改变。
服务器做的什么事啊总结一句话:服务器把特殊后缀名的文件进行处理返回给前端展示。 我们可以模拟vite的devServe,使用koa中间件启动一个本地服务。 // 引入依赖const Koa = require('koa')const app = new Koa()const fs = require('fs')const path = require('path')const compilerSfc = require('@vue/compiler-sfc')const compilerDom = require('@vue/compiler-dom')app.use(async (ctx) => { const { url, query } = ctx.request // 处理请求资源代码都写这})app.listen(3001, () => { console.log('dyVite start!!')})
请求首页index.html if (url === '/') { const p = path.join(__dirname, './index.html') // 绝对路径 // 首页 ctx.type = 'text/html' ctx.body = fs.readFileSync(p, 'utf8') } 
看到上面这张图,就知道我们的宿主文件已经请求成功了。只是浏览器又给服务端发送的一个main.js文件的请求。这时,我们还需要判断处理一下main.js文件。
请求以.js结尾的文件我们处理上述情况后,emmmm。。。发现main中还是存在好多其他资源请求。
基础js文件main文件: 处理main: |