Vite 发展现状与回顾:从“极致开发体验”到生态基础设施

0 阅读11分钟

一、引言:从“慢如乌龟”的打包,到“秒起”的开发服务器

在现代前端开发中,“等待”曾经是开发者最深的痛点之一:

  • 启动开发服务器要几十秒甚至一分钟;
  • 改一行代码,热更新需要几秒钟;
  • 项目越来越大,构建越来越慢。

Vite 正是在这样的背景下诞生的。它由 Vue 作者尤雨溪发起,但并不仅仅服务于 Vue,而是试图从根本上改造前端开发体验——利用浏览器原生 ES Modules 能力,在开发阶段不再做整体打包,从而实现“秒级冷启动”“毫秒级热更新”。

经过几年的发展,Vite 已经从“新玩具”成长为主流前端工具链之一,并逐渐演化为一套框架无关、插件生态丰富、可作为底层基建的构建工具。

本文将系统回顾 Vite 的发展脉络与现状,介绍它解决了什么问题、如何实现、有哪些优缺点,并结合实践给出使用建议和未来展望。


二、背景与问题:传统打包工具的瓶颈

2.1 传统开发流程的痛点

在 Vite 之前,主流的前端构建工具是 Webpack、Rollup、Parcel 等。它们大致遵循同一个工作模式:

  1. 构建前解析整个依赖图(从入口文件开始,递归分析 import/require);
  2. 对所有模块进行打包、转换、压缩
  3. 输出一个或多个 bundle(如 app.jsvendor.js 等);
  4. 开发时借助内存文件系统和 HMR 插件来实现热更新。

在项目规模较小时,这种模式还算可接受。然而,当你面对的是一个大型单页应用(SPA)或多页应用(MPA)时,问题凸显:

  • 冷启动慢:

    • 首次启动 dev server,需要构建完整 bundle,几十秒乃至数分钟;
  • 热更新慢:

    • 修改一个组件,工具需要重新构建受影响的模块树,随着项目增大愈发明显;
  • 配置复杂:

    • 特别是 Webpack,配置复杂度陡增,各种 loader、plugin 的组合需要很强经验;
  • 现代特性支持滞后:

    • 比如原生 ES Modules、HTTP2、多核并行等,工具演进相对缓慢。

总结一下,是“重打包、重构建、重配置”导致了开发体验上的痛苦。

2.2 浏览器原生 ESM 带来的新机会

随着现代浏览器基本都支持 原生 ES Modules(ESM)

<script type="module" src="/src/main.js"></script>

浏览器可以直接解析 JavaScript 模块、处理 import 语句,而不再强制依赖打包工具把所有内容“打平”到一个文件里。这带来了一个关键启发:

既然浏览器可以帮我们处理模块加载,开发阶段是否可以完全不打包,只在需要时对单个模块做编译?

Vite 正是抓住了这个机会,提出了**“按需编译 + 原生 ESM”**的开发模式。


三、Vite 的方案与技术实现

3.1 核心理念概述

Vite 可以拆分成两个阶段的不同角色:

  1. 开发阶段(dev server)

    • 利用原生 ESM
    • 实现无需打包的极速冷启动按需转换,配合 HMR
  2. 生产阶段(build)

    • 默认使用 Rollup 进行传统打包优化(代码分割、Tree-shaking、压缩等)
    • 保证产物体积、兼容性与性能

这个“双形态”的设计兼顾了开发体验和生产性能。

3.2 开发模式:按需编译 + 原生 ESM

Vite 的开发服务器主要做几件事:

  1. 拦截浏览器请求
    浏览器访问 http://localhost:5173/src/main.ts 时,Vite 接管请求。

  2. 对源码做最小必要的编译与转换
    如:

    • TypeScript -> JavaScript
    • JSX/TSX -> JavaScript
    • .vue 单文件组件解析
    • PostCSS / CSS Modules 处理
    • 路径别名重写、依赖预构建处理
  3. 按请求返回结果
    每个模块是一个独立的 HTTP 响应,浏览器通过 ESM 按需加载依赖。

这种方式带来的直接好处:

  • 冷启动几乎只依赖“服务器启动时间”,而非“打包全量依赖时间”;
  • 第一次访问页面时,只会编译当前路由实际加载的模块;
  • 模块编译结果可以被缓存,后续请求快很多。

3.2.1 简单示例:Vite + Vue

安装与初始化:

# 使用 npm 也可以
pnpm create vite@latest my-vite-app --template vue-ts
cd my-vite-app
pnpm install
pnpm dev

main.ts 内容示例:

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

Vite 在开发模式下并不会预先打包 vue 和你的组件,而是在浏览器请求到 /src/main.ts 时动态编译并返回。

3.3 依赖预构建(Dependency Pre-Bundling)

尽管使用原生 ESM,第三方依赖(如 reactlodash)往往仍然采用 CommonJS 或 UMD 格式。直接用 ESM 加载这些依赖会有两个问题:

  1. 大量小文件请求:有些库(如 lodash-es)按模块拆分,ESM 导致 N 多 HTTP 请求;
  2. 兼容性问题:CJS/UMD 需要转为 ESM。

Vite 的解决方案是预构建依赖

  • 启动时扫描你的依赖;
  • 使用 esbuild 将它们打包成少量的 ESM 文件;
  • 后续开发过程中直接从预构建产物中加载依赖。

这既解决了“请求过多”问题,又兼顾了 CommonJS 的兼容性。

配置示例:

// vite.config.ts
import { defineConfig } from 'vite'

export default defineConfig({
  optimizeDeps: {
    include: ['lodash-es', 'axios'],
    exclude: ['some-big-lib'] // 可以跳过某些库
  }
})

3.4 生产构建:基于 Rollup 的打包

到了生产阶段,不能再“裸奔模块”——我们更关心:

  • 文件体积;
  • 加载策略(代码分割);
  • Tree-shaking 与缓存策略。

Vite 默认使用 Rollup 作为打包引擎,优势是:

  • 成熟稳定的打包生态;
  • 优秀的 Tree-shaking 与代码分割;
  • 插件体系与 Vite 兼容性好。

build 配置示例:

// vite.config.ts
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    target: 'es2018',
    sourcemap: true,
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['vue', 'vue-router']
        }
      }
    }
  }
})

构建命令:

pnpm build
pnpm preview

3.5 插件体系与框架集成

Vite 的插件系统设计与 Rollup 高度兼容,同时扩展了开发服务器相关的钩子(如中间件、HMR 钩子)。

一个最简单的 Vite 插件示例:

// vite.config.ts
import { defineConfig } from 'vite'
import type { Plugin } from 'vite'

function mySimplePlugin(): Plugin {
  return {
    name: 'my-simple-plugin',
    enforce: 'pre', // pre / post
    transform(code, id) {
      if (id.endsWith('.js')) {
        // 简单示例:自动注入一行日志
        return {
          code: `console.log('[my-plugin] loaded: ${id}');\n` + code,
          map: null
        }
      }
      return null
    }
  }
}

export default defineConfig({
  plugins: [mySimplePlugin()]
})

许多现代框架都直接将 Vite 作为默认工具:

  • Vue 3create-vue 默认使用 Vite;
  • Reactcreate-vite 提供 React 模板,许多项目迁移中;
  • SvelteKit:基于 Vite;
  • SolidStart、Qwik、UnoCSS 等:都直接深度集成 Vite。

3.6 Vite 的周边生态:从工具到平台

随着 Vite 成功,出现了大量基于 Vite 的“更上层抽象”:

  • Vitest:基于 Vite 的测试框架,提供快速、近似原生 ESM 环境的单测体验;
  • VitePress:官方维护的文档站点生成器,用于构建静态站点;
  • Storybook 的 Vite Builder:将 Vite 用于组件开发环境;
  • 各种 Vite SSR/SSG 方案:如 vite-ssgvite-plugin-ssr 等。

这说明,Vite 不再只是“一个 bundler 的替代品”,而是成为前端工具生态的底层“runtime + 打包平台”


四、代码示例:构建一个简单但完整的 Vite 项目

下面用一个稍完整一点的例子,展示 Vite 的几个常见能力点(TS 支持、环境变量、别名、按需组件)。

4.1 项目初始化

pnpm create vite@latest vite-demo --template vue-ts
cd vite-demo
pnpm install
pnpm dev

4.2 配置别名与环境变量

vite.config.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'node:path'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '@components': path.resolve(__dirname, 'src/components')
    }
  },
  server: {
    port: 5173,
    open: true,
    proxy: {
      // 将 /api 开头的请求代理到后端
      '/api': {
        target: 'http://localhost:3000',
        changeOrigin: true,
        rewrite: path => path.replace(/^/api/, '')
      }
    }
  }
})

环境变量文件:

# .env.development
VITE_API_BASE_URL=http://localhost:3000

# .env.production
VITE_API_BASE_URL=https://api.example.com

在代码中使用:

// src/services/http.ts
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL

export async function getUser(id: number) {
  const res = await fetch(`${API_BASE_URL}/users/${id}`)
  return res.json()
}

4.3 按需加载页面组件

路由配置示例(以 vue-router 为例):

// src/router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'

const routes: RouteRecordRaw[] = [
  {
    path: '/',
    name: 'home',
    component: () => import('@/views/HomePage.vue')
  },
  {
    path: '/about',
    name: 'about',
    component: () => import('@/views/AboutPage.vue')
  }
]

export const router = createRouter({
  history: createWebHistory(),
  routes
})

Vite 在开发阶段不会对这些路由组件做整体打包,而是在你访问 /about 路由时,才会请求 AboutPage.vue 对应的模块;构建时,则由 Rollup 进行代码分割,生成独立的 chunk。


五、优缺点分析与实践建议

5.1 优点分析

  1. 极快的开发体验

    • 冷启动:大部分中小项目都是“秒起”,大型项目相比传统工具也快一个数量级;
    • 热更新速度快:只重新编译受影响模块,不需全局重打包;
    • 源码即运行:原生 ESM 思路更贴近浏览器行为。
  2. 开箱即用、配置简洁

    • 默认配置能满足绝大多数项目;
    • TS、JSX/TSX、CSS 预处理器等支持友好;
    • 与传统 Webpack 对比,配置量往往减少 50% 以上。
  3. 生态繁荣、框架友好

    • Vue / React / Svelte / Solid 等都有成熟的官方/社区整合方案;
    • 插件丰富,如 unplugin-auto-importunplugin-vue-componentsvite-plugin-inspect 等;
    • 学习成本相对较低,官方文档清晰。
  4. 生产构建品质可靠

    • 依托 Rollup 的成熟稳定;
    • Tree-shaking 与代码分割表现良好;
    • 配合现代浏览器的 ESM + HTTP/2,可实现良好加载性能。
  5. 适合作为底层开发平台

    • 许多上层框架已将 Vite 视为“runtime + bundler”基础;
    • 易于构建自定义脚手架和应用框架。

5.2 局限与潜在问题

  1. 对非 ESM 生态的适配成本

    • 虽然依赖预构建解决了大量问题,但一些老旧库适配依旧麻烦;
    • 超大型、极其复杂的依赖树下,依赖扫描和预构建有时会出问题,需要手动 include/exclude。
  2. 在极大型单仓、多包项目中的复杂度

    • Monorepo(例如多个 packages 共享同一 Vite 项目)场景下,如何优雅地处理依赖预构建、缓存、别名,有一定门槛;
    • 虽然 Vite 已支持 monorepo 场景,但与诸如 Turborepo、Nx 等工具配合时仍需摸索。
  3. 插件生态成熟度不完全均衡

    • 核心插件质量很高,但部分社区插件质量参差不齐;
    • 相比 Webpack 多年积累的“长尾插件”,某些特定领域(如极个别老式模块系统)支持度略弱。
  4. SSR 与复杂场景仍需实践经验

    • Vite 虽支持 SSR,但具体到“同构应用、边缘渲染、多入口 SSR”时,需要依据各自框架生态来做;
    • 一些高阶需求(如微前端、复杂多页 + SSR)需要更多经验或专门框架支持。

5.3 实战中的使用建议

  1. 中小型 Web 应用:优先选 Vite

    • Vue/React 新项目可以直接用 Vite 脚手架;
    • 配置简单、开发体验极佳、学习曲线平缓。
  2. 增量迁移旧项目

    • 对于基于 Webpack 的老项目,可以考虑:

      • 新模块/新子项目使用 Vite;
      • 逐步把老项目拆分为多包或独立子系统,引入 Vite;
    • 不必一次性“重构全部”,避免风险。

  3. Monorepo/微前端场景

    • 若已有 Turborepo/Nx,可将 Vite 用作每个包的 dev server / build 工具;
    • 合理利用 build.libbuild.rollupOptions 等配置来构建可复用库;
    • 多应用集成可用 Module Federation(需社区方案)或通过 Nginx/网关统一路由。
  4. 性能调优建议

    • 充分利用依赖预构建配置 optimizeDeps
    • 注意排查“动态 import 太多导致的 chunk 过碎”问题;
    • 结合浏览器 DevTools + rollup-plugin-visualizer 分析产物体积。
  5. 团队落地建议

    • 尽量通过模板化脚手架(如自建 create-xxx)固化团队最佳实践;
    • 统一 ESLint/Prettier/TSconfig 等基础配置,配合 Vite 模板;
    • 关注 Vite 与框架生态的版本兼容矩阵,避免“乱升版本”。

六、发展现状与未来趋势

6.1 现状:从“新秀”到“主流基础设施”

截至目前,Vite 已广泛用于:

  • Vue 官方文档站、生态站点(VitePress 自吃狗粮);
  • 各类开源项目、管理后台、文档系统、低代码平台;
  • 商业级应用:在国内外均有大量“中大型项目在生产环境中长期运行”。

更重要的是,Vite 逐渐从“单一项目开发工具”演化为:

  • 底层构建能力(构建库、组件库、SDK);
  • 各种框架(如 SvelteKit、QwikCity)的默认开发环境;
  • 配套生态(Vitest、VitePress)构成的“工具平台”。

6.2 未来可能的发展方向

  1. 更深入的 SSR / SSG 支持

    • 更好的 SSR API;
    • 在多入口 SSR、边缘渲染(Edge Runtime)、Island Architecture 上发力;
    • 与云原生平台(Vercel、Netlify 等)的集成增强。
  2. 与 RSC / 新一代框架模式的适配

    • React Server Components、Streaming SSR、Partial Hydration 等新范式;
    • 更细粒度的构建与运行时配合。
  3. 大型项目的工程化增强

    • 更好的 monorepo 支持(尤其是与 pnpm workspace、turborepo 的深度集成);
    • 更智能的缓存、增量构建和分布式构建能力。
  4. 工具链一体化

    • 测试(Vitest)、文档(VitePress)、图形组件开发(Storybook with Vite)进一步整合;
    • 打造真正“一栈式”前端工程体验。

七、结论:Vite 的价值与选择建议

综上,Vite 的关键价值可以概括为三点:

  1. 极致开发体验:原生 ESM + 按需编译,让“冷启动秒级、热更毫秒级”成为现实;
  2. 生态与平台化:不仅是替代 Webpack 的工具,更是承载现代前端框架的基础设施;
  3. 工程实践可落地:在中小型项目中“即插即用”,在中大型项目中也已积累了大量实践经验。

对于前端团队来说:

  • 如果你要开启一个新的 Vue / React / Svelte 项目,Vite 几乎是首选
  • 如果你维护的是一个老旧的 Webpack 巨石应用,可以考虑将 Vite 作为增量迁移的目标方向
  • 如果你在设计自研框架或平台,Vite 是非常合适的底层构建与开发平台候选。

未来,随着浏览器能力与运行时环境持续演进,Vite 很可能继续在“前端开发体验”这条主线上迭代,成为更多框架、平台的默认基础层。


八、参考资料与进一步学习