Skip to content

Vite 的模块化加载流程与 module script 特性

Vite 利用了浏览器原生对 ECMAScript Module(ESM)的支持,让模块的加载和依赖解析直接由浏览器完成,因此可以天然地实现按需加载和懒加载。Vite 在开发时并不需要像传统打包工具那样提前打包所有代码,而是在浏览器请求某个源码文件时,即时地对源码中的模块进行转换,然后返回给浏览器。之后,浏览器会根据实际需要自动请求相关模块,从而大大提升了开发时的响应速度和构建效率。


1. 静态服务搭建

  • Vite 启动时会自动搭建一个本地静态服务(dev server),监听前端资源请求。

2. 中间件拦截与资源处理

  • Vite 内部通过中间件(middleware)拦截所有 HTTP 请求,根据不同类型资源进行处理:

JS 模块请求

  1. 路径重写与依赖解析

    • 如果响应类型为 .js,先读取响应体内容。
    • 使用 es-module-lexer 分析 AST,提取 import 的模块名。
    • 遍历所有依赖,判断是否为 npm 模块(即路径不以 ./ 开头)。
    • 对 npm 模块进行路径重写,如 vue => /@modules/vue
  2. 动态依赖请求

    • 修改后的 JS 内容返回给浏览器。
    • 浏览器解析 import 语句后,会继续请求 /@modules/vue 这类模块。(ESM 天然支持按需加载和懒加载,未使用到的 npm 模块不会发起请求)
    • 中间件再次拦截,检测请求路径是否包含 /@modules/
    • 若是 npm 依赖,则将 /@modules/ 替换为空,/@modules/vue -> vue,获取真实模块名并从 node_modules 中读取实际文件内容返回。

非 JS 静态资源

  • 其它如 CSS/图片等资源,Vite 也有相应插件和中间件做专门处理,但主流程类似:拦截请求,按需转换,返回浏览器可识别的格式。

3. Vue 单文件组件(.vue)处理

  • 浏览器原生不支持 .vue 文件,因此 Vite 做了如下专门处理:
  1. 优先处理 .vue 文件

    • 如果请求路径以 .vue 结尾,说明是 SFC(单文件组件)。
    • Vite 使用 @vue/compiler-sfc 解析该文件,拆分出 template、script、style 等部分。
  2. 输出 JS 代码串

    • 通过字符串拼接 JS 代码,并处理 import 的第三方依赖。

    • 若是 template 部分,会在 URL 上加 ?type=template,如 App.vue?type=template 供后续请求。

    js
    import { render as __render } from "/App.vue?type=template"
    export default {
        data() {
            return {
            msg: 'Hello Vite!'
            }
        },
        render: __render
    }
    // 样式部分会被 Vite 以 <style> 注入或通过 CSS 插件处理
  3. 模板编译

    • 浏览器请求 template 部分时,Vite 检查 ctx.query.type,若为 template,则用 compileTemplate 将 HTML 模板编译成 AST,再生成渲染函数。
  4. 依赖递归解析

    • .vue 文件中如有其它依赖(包括 npm 包、其它 .vue 文件),继续递归上述步骤,直到所有依赖被浏览器加载完成。

4. 典型工作流小结

  1. 浏览器加载 index.html,发现 <script type="module" src="main.js">
  2. main.js 中 import 了 App.vue,Vite 拦截 /App.vue,转换为 JS
  3. App.vue import 了第三方依赖 vue,被重写成 /@modules/vue,由 Vite 处理并返回 node_modules 下的实际代码
  4. App.vue 中的 template 被请求为 /App.vue?type=template,用 Vue 编译器编译为 render 函数
  5. 所有依赖递归加载,最终完整挂载页面

5. 优势及特性

  • 即时依赖解析:按需请求和转换源码,无需预打包。
  • 极致开发体验:修改文件秒级热更(HMR),无全量打包等待。
  • 利用浏览器原生能力:模块依赖解析、缓存、并发加载都交给浏览器完成。
  • 灵活中间件体系:可扩展自定义文件类型处理流程。

6. 补充说明

  • 生产环境构建:Vite 开发时利用 ESM,生产阶段采用 Rollup 打包生成兼容传统浏览器的 bundle。
  • 多种资源类型支持:Vite 通过插件机制扩展对 CSS、JSON、图像、Web Worker 等资源的模块化支持。
  • 动态 import:Vite 支持原生 import() 语法,只有真正需要的模块才会被请求和处理。