学习笔记--Vite知识总结

51 阅读16分钟

一、Vite 核心原理

Vite 的核心优势源于其对开发环境和生产环境的差异化设计,核心原理可概括为“开发时基于 ESM 按需编译,生产时基于 Rollup 优化打包”。

1.1 开发环境原理(ESM 驱动)

传统构建工具(如 Webpack)在开发时会先将所有模块打包成一个或多个bundle,再提供给浏览器,启动速度随项目规模增长急剧下降。而 Vite 彻底抛弃了这种“全量打包”模式,利用浏览器对 ESM 的原生支持,实现“按需编译”:

  • 原生 ESM 加载:Vite 启动后仅作为开发服务器,不会提前打包所有文件。当浏览器请求入口文件(如 index.html)时,Vite 会将其中的 script 标签改为 type="module",使浏览器以 ESM 方式加载模块。
  • 按需编译与转换:浏览器加载模块时,会通过网络请求逐个获取依赖。Vite 拦截这些请求,对模块进行实时编译(如将 Vue/Svelte 单文件组件编译为 JS 模块、将 TypeScript 转换为 JS、处理 CSS 预处理器等),再返回给浏览器。仅当模块被请求时才进行编译,启动速度不受项目规模影响。
  • 依赖预构建:第三方依赖(如 node_modules 中的包)大多不是 ESM 格式(可能是 CommonJS、UMD),且依赖层级深。Vite 会在首次启动时,通过 esbuild 将第三方依赖预构建为 ESM 格式并缓存,避免每次请求都进行转换,同时合并重复依赖,减少网络请求次数。预构建结果默认缓存于 node_modules/.vite 目录,依赖变动时会自动重新构建。

1.2 生产环境原理(Rollup 打包)

开发环境的 ESM 模式虽快,但存在浏览器兼容性问题(部分旧浏览器不支持 ESM)且缺乏生产级优化。因此 Vite 生产环境采用 Rollup 进行打包,原因如下:

  • Rollup 优势:Rollup 天生擅长 Tree-shaking(消除未使用代码)、代码分割、模块合并,打包产物体积更小、更高效,适合生产环境。
  • 优化策略:Vite 对 Rollup 进行了深度封装,默认提供代码分割、Tree-shaking、CSS 提取、压缩、哈希命名、懒加载等生产级优化,同时支持通过配置扩展 Rollup 功能。

1.3 关键技术支撑

  • esbuild:由 Go 语言编写的超快速 JavaScript 打包器/编译器,比传统 JS 编写的工具快 10-100 倍。Vite 用它进行依赖预构建、开发时的 TS/JSX 转换、生产环境的代码压缩(替代 Terser),大幅提升构建速度。
  • Rollup:作为生产环境打包核心,负责模块合并、优化、输出最终产物。
  • Koa:Vite 开发服务器基于 Koa 实现,提供请求拦截、中间件机制,支持自定义请求处理逻辑。

二、Vite 核心特性

2.1 极致的开发体验

  • 极速启动:开发环境无需全量打包,启动时间毫秒级,大型项目也能秒开。
  • 即时热更新(HMR) :基于 ESM 实现的 HMR 机制,仅更新修改的模块,而非整个页面,更新速度快且状态保留(如 Vue 组件的 props、state 不会因热更新丢失)。Vite 对框架 HMR 进行了深度优化,支持 Vue、React、Svelte 等框架的细粒度 HMR。
  • 无配置启动:支持零配置运行,默认处理 JS、TS、CSS、HTML、静态资源等,无需手动配置 loader 或 plugin。

2.2 丰富的内置功能

  • 模块支持:原生支持 ESM、CommonJS、UMD 模块,自动处理模块格式转换。
  • 语言与预处理器:内置支持 TypeScript、JSX、CSS 预处理器(Sass/SCSS、Less、Stylus)、PostCSS,无需额外安装 loader,仅需安装对应预处理器依赖即可使用(如使用 Sass 需安装 sass 包)。
  • 静态资源处理:支持图片、字体、JSON、WASM 等静态资源,小于一定体积(默认 4KB)的资源会被转为 base64 嵌入代码,减少网络请求;也可通过配置自定义资源处理规则。
  • CSS 功能:支持 CSS Modules、CSS 嵌套、CSS 代码分割、关键 CSS 提取(生产环境)。
  • 环境变量:内置环境变量管理,支持 .env、.env.development、.env.production 等文件,通过 import.meta.env 访问变量,默认提供 NODE_ENV、BASE_URL 等变量。

2.3 灵活的扩展性

  • 插件系统:基于 Rollup 插件 API 设计,同时扩展了 Vite 专属钩子,支持开发环境和生产环境的自定义逻辑,生态丰富(如 vite-plugin-vue、vite-plugin-react 等框架插件)。
  • Rollup 配置扩展:生产环境可直接扩展 Rollup 配置,满足复杂的打包需求(如自定义输出格式、添加 Rollup 插件)。
  • 中间件扩展:开发服务器支持自定义 Koa 中间件,可拦截请求、修改响应、集成后端接口等。

2.4 框架无关性

Vite 并非专为 Vue 设计,而是通用构建工具,官方提供了对 Vue、React、Svelte、Preact 等主流框架的模板支持,同时也支持 vanilla JS/TS 项目,适配不同技术栈需求。

三、Vite 配置详解

Vite 的配置文件为项目根目录下的 vite.config.js 或 vite.config.ts,采用 ESM 语法(默认导出一个配置对象)。配置对象包含多个核心选项,以下是常用选项的详细说明:

3.1 基础配置

  • root:项目根目录(默认 process.cwd()),指定后所有相对路径配置都基于此目录。
  • base:项目部署的基础路径(默认 '/'),适用于非根目录部署场景(如 GitHub Pages),例如 base: '/my-project/'。
  • mode:运行模式(默认由命令行参数决定,开发时为 development,构建时为 production),可通过配置强制指定,影响环境变量加载和插件行为。
  • define:定义全局常量替换规则,类似 Webpack 的 DefinePlugin。例如:define: { 'process.env.VUE_APP_TITLE': JSON.stringify('My App') }。注意:Vite 中不建议直接定义 window 变量,可通过 import.meta.env 替代。

3.2 服务器配置(server)

用于配置开发服务器,核心选项如下:

  • host:服务器主机名(默认 'localhost'),设置为 '0.0.0.0' 可允许外部设备访问。
  • port:服务器端口(默认 5173),端口被占用时会自动递增。
  • open:启动后自动打开浏览器(默认 false),可指定打开的路径(如 open: '/docs')。
  • proxy:配置跨域代理,解决开发时接口跨域问题,格式与 Webpack devServer.proxy 类似。例如: server: { `` proxy: { `` '/api': { `` target: 'http://localhost:3000', // 后端接口地址 `` changeOrigin: true, // 允许跨域 `` rewrite: (path) => path.replace(/^/api/, '') // 重写路径,去掉 /api 前缀 `` } `` } ``}
  • hmr:配置 HMR 相关选项(默认开启),可设置 hmr: false 关闭 HMR,或自定义 HMR 服务器地址(适用于跨域场景)。
  • https:是否启用 HTTPS(默认 false),可传入证书配置(如 { key: fs.readFileSync('key.pem'), cert: fs.readFileSync('cert.pem') })。

3.3 构建配置(build)

用于配置生产环境打包,核心选项如下:

  • outDir:输出目录(默认 'dist'),打包后的文件会放入此目录。
  • assetsDir:静态资源目录(默认 'assets'),用于存放图片、字体等资源,最终输出到 outDir/assets。
  • assetsInlineLimit:静态资源转为 base64 的阈值(默认 4096 字节,即 4KB),超过阈值的资源会单独生成文件。
  • cssCodeSplit:是否将 CSS 拆分为单独的文件(默认 true,生产环境),设置为 false 会将所有 CSS 嵌入到 JS 中,通过动态创建 style 标签注入。
  • sourcemap:是否生成 sourcemap(默认 false,生产环境),可设置为 'inline'、'hidden' 等模式,用于线上调试。
  • minify:代码压缩工具(默认 'esbuild',生产环境),esbuild 压缩速度远快于 Terser,也可设置为 'terser' 并配合 terserOptions 自定义压缩规则。
  • rollupOptions:扩展 Rollup 配置,直接传递给 Rollup 的打包配置,例如自定义输出格式、代码分割规则、外部依赖等。示例: build: { `` rollupOptions: { `` output: { `` // 自定义 chunk 命名规则 `` chunkFileNames: 'js/[name]-[hash].js', `` entryFileNames: 'js/[name]-[hash].js', `` assetFileNames: '[ext]/[name]-[hash].[ext]' `` }, `` // 外部依赖,不打包进产物 `` external: ['lodash'] `` } ``}
  • emptyOutDir:打包前是否清空 outDir(默认 true),适用于需要保留历史文件的场景。

3.4 模块解析配置(resolve)

用于配置模块解析规则,核心选项如下:

  • extensions:默认解析的文件扩展名(默认 ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json']),导入模块时可省略这些扩展名。
  • alias:配置路径别名,简化模块导入,类似 Webpack 的 resolve.alias。示例: resolve: { `` alias: { `` '@': path.resolve(__dirname, 'src'), `` 'components': path.resolve(__dirname, 'src/components') `` } `` } 配置后可通过 import Foo from '@/components/Foo.vue' 导入模块。
  • modules:解析第三方依赖的目录(默认 ['node_modules']),可添加自定义目录。

3.5 CSS 配置(css)

用于配置 CSS 相关处理规则,核心选项如下:

  • modules:CSS Modules 配置,可自定义类名生成规则、作用域等。示例: css: { `` modules: { `` generateScopedName: '[name]-[hash]-[local]', // 自定义类名格式 `` scopeBehaviour: 'local' // 作用域模式(local/global) `` } ``}
  • preprocessorOptions:CSS 预处理器全局配置,用于传递预处理器的全局变量、导入全局样式等。示例(Sass): css: { `` preprocessorOptions: { `` scss: { additionalData: @import "@/styles/variables.scss"; // 全局导入变量文件 } `` } ``}
  • postcss:PostCSS 配置,可指定 postcss.config.js 文件路径,或直接传入配置对象。
  • devSourcemap:是否生成 CSS sourcemap(默认 false,开发环境),用于调试 CSS。

3.6 插件配置(plugins)

用于配置 Vite 插件,插件是扩展 Vite 功能的核心方式。配置格式为数组,支持官方插件和第三方插件。示例:


import vue from '@vitejs/plugin-vue'; // Vue 插件
import react from '@vitejs/plugin-react'; // React 插件
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    vue(), // Vue 单文件组件支持
    react({ /* React 插件配置 */ })
  ]
});
    

四、Vite 插件系统

Vite 插件基于 Rollup 插件 API 设计,同时补充了 Vite 专属钩子,以适配开发环境的 ESM 模式和 HMR 机制。插件可实现自定义模块转换、请求拦截、HMR 处理、打包优化等功能。

4.1 插件结构

一个 Vite 插件通常是一个函数,返回一个包含插件钩子的对象。示例:


function myVitePlugin(options = {}) {
  return {
    name: 'my-vite-plugin', // 插件名称,用于调试和冲突检测
    enforce: 'pre', // 插件执行顺序(pre:在核心插件前执行,post:在核心插件后执行)
    // Rollup 钩子(生产环境打包时执行)
    transform(code, id) {
      // 转换模块代码,id 为模块路径
      if (id.endsWith('.vue')) {
        return code.replace(/foo/g, 'bar');
      }
    },
    // Vite 专属钩子(开发环境执行)
    configureServer(server) {
      // 配置开发服务器,可添加中间件、监听 HMR 事件等
      server.middlewares.use((req, res, next) => {
        if (req.url === '/custom') {
          res.end('Hello from custom middleware');
        } else {
          next();
        }
      });
    },
    // HMR 钩子,处理模块热更新
    handleHotUpdate(ctx) {
      // ctx 包含更新的模块信息,可自定义 HMR 逻辑
      if (ctx.file.endsWith('.scss')) {
        // 通知所有依赖该 SCSS 文件的模块更新
        ctx.server.ws.send({
          type: 'update',
          updates: [{
            type: 'js-update',
            path: ctx.file,
            acceptedPath: ctx.file
          }]
        });
        return []; // 阻止默认 HMR 行为
      }
    }
  };
}
    

4.2 核心钩子分类

4.2.1 Rollup 钩子

Vite 生产环境打包基于 Rollup,因此支持大部分 Rollup 钩子,常用钩子如下:

  • transform:转换模块代码,可用于修改 JS/CSS/HTML 内容。
  • resolveId:自定义模块解析逻辑,可重写模块路径。
  • load:加载模块内容,可用于虚拟模块(无需真实文件)。
  • generateBundle:打包完成后修改输出产物,可用于添加版权信息、修改文件内容等。

4.2.2 Vite 专属钩子

为适配开发环境的 ESM 模式和 HMR,Vite 扩展了以下专属钩子:

  • configureServer:配置开发服务器,可添加中间件、监听服务器事件、扩展 HMR 功能。
  • handleHotUpdate:处理模块热更新,可自定义更新逻辑、过滤更新模块、发送自定义 HMR 消息。
  • configurePreviewServer:配置预览服务器(vite preview 命令启动的服务器),类似 configureServer。
  • resolveId(Vite 扩展):与 Rollup resolveId 类似,但支持开发环境的 ESM 解析。

4.3 常用官方插件

  • @vitejs/plugin-vue:Vue 3 支持插件,处理 .vue 单文件组件,支持模板编译、脚本转换、样式处理等。
  • @vitejs/plugin-vue-jsx:Vue 3 JSX/TSX 支持插件,允许在 Vue 项目中使用 JSX 语法。
  • @vitejs/plugin-react:React 支持插件,处理 JSX/TSX 语法,自动注入 React 运行时,支持 Fast Refresh(快速热更新)。
  • @vitejs/plugin-react-swc:React 插件的 SWC 版本,用 SWC 替代 Babel 转换 JSX/TSX,速度更快。
  • @vitejs/plugin-legacy:为旧浏览器提供兼容性支持,生成传统 ES5 代码和 polyfill,适配 IE11 等浏览器。

五、Vite 与主流框架集成

5.1 Vue 3 集成

Vite 对 Vue 3 提供原生支持,推荐使用官方模板创建项目:


# npm
npm create vite@latest my-vue-app -- --template vue
# yarn
yarn create vite my-vue-app --template vue
# pnpm
pnpm create vite my-vue-app --template vue
    

项目创建后,自动安装 @vitejs/plugin-vue 插件,支持 .vue 单文件组件、CSS 预处理器、HMR 等功能。如需使用 TypeScript,可选择 vue-ts 模板。

5.2 React 集成

使用官方 React 模板创建项目,默认集成 @vitejs/plugin-react 或 @vitejs/plugin-react-swc:


# React + JS
npm create vite@latest my-react-app -- --template react
# React + TS
npm create vite@latest my-react-app -- --template react-ts
# React + TS + SWC
npm create vite@latest my-react-app -- --template react-swc-ts
    

集成后支持 React Fast Refresh、JSX/TSX 语法、环境变量等功能,构建速度远快于 Create React App。

5.3 Svelte 集成

使用 Svelte 官方模板创建 Vite 项目:


npm create vite@latest my-svelte-app -- --template svelte
# Svelte + TS
npm create vite@latest my-svelte-app -- --template svelte-ts

自动安装 @sveltejs/vite-plugin-svelte 插件,支持 Svelte 组件编译、HMR 等功能。

5.4 Vanilla JS/TS 集成

创建纯 JS/TS 项目,无需额外框架插件:


# Vanilla JS
npm create vite@latest my-vanilla-app -- --template vanilla
# Vanilla TS
npm create vite@latest my-vanilla-app -- --template vanilla-ts
    

默认支持 ESM 导入、静态资源处理、TS 转换等功能,适合简单项目或库开发。

六、Vite 生产构建优化

Vite 生产环境默认提供了诸多优化,但针对大型项目,仍可通过以下方式进一步优化构建产物和性能:

6.1 代码分割优化

  • 路由级代码分割:结合框架路由(如 Vue Router、React Router),使用动态 import() 语法实现路由懒加载,将不同路由对应的组件拆分为独立 chunk,减少首屏加载体积。示例(Vue Router): const Home = () => import('@/views/Home.vue'); `` const About = () => import('@/views/About.vue'); ```` const routes = [ `` { path: '/', component: Home }, `` { path: '/about', component: About } ``];
  • 第三方依赖分割:通过 build.rollupOptions.output.manualChunks 将第三方依赖(如 vue、react、lodash)拆分为独立 chunk,利用浏览器缓存机制,减少重复加载。示例: build: { `` rollupOptions: { `` output: { `` manualChunks: { `` // 将 vue 相关依赖拆分为 vueChunk `` vueChunk: ['vue', 'vue-router', 'pinia'], `` // 将 react 相关依赖拆分为 reactChunk `` reactChunk: ['react', 'react-dom', 'react-router-dom'] `` } `` } `` } ``}

6.2 静态资源优化

  • 图片压缩:使用第三方插件(如 vite-plugin-imagemin)对图片进行压缩,减少资源体积。
  • 字体优化:使用 font-display: swap 优化字体加载,避免页面闪烁;对字体文件进行 subset 处理,只保留常用字符。
  • base64 合理使用:调整 assetsInlineLimit 阈值,仅将小体积资源转为 base64,避免大体积资源导致 JS 文件过大。

6.3 性能优化

  • Tree-shaking 强化:确保代码符合 ES 模块规范(避免使用 CommonJS 的 require/module.exports),以便 Rollup 更好地消除未使用代码。
  • CSS 优化:启用 cssCodeSplit 拆分 CSS,提取关键 CSS(通过 vite-plugin-critical 等插件),优先加载首屏所需 CSS。
  • 预加载与预连接:在 index.html 中添加 link 标签的 preload、prefetch、preconnect 属性,优化资源加载顺序。
  • 压缩优化:使用 esbuild 压缩(默认),如需更精细的压缩规则,可切换为 Terser 并配置压缩选项。

6.4 兼容性优化

使用 @vitejs/plugin-legacy 为旧浏览器提供支持,自动生成 ES5 代码和 polyfill:


import legacy from '@vitejs/plugin-legacy';

export default defineConfig({
  plugins: [
    legacy({
      targets: ['defaults', 'not IE 11'] // 目标浏览器范围
    })
  ]
});
    

七、Vite 与 Webpack 对比

Vite 和 Webpack 是当前最主流的两款前端构建工具,各有优劣,适用场景不同,核心对比如下:

对比维度ViteWebpack
开发环境启动速度极快(毫秒级),基于 ESM 按需编译,无全量打包较慢,需全量打包所有模块,速度随项目规模增长下降
热更新速度即时,细粒度 HMR,仅更新修改模块较快,但需重新打包修改模块及依赖,大型项目有延迟
生产环境打包基于 Rollup,优化好、产物体积小,配置简单内置打包功能,配置灵活,支持复杂场景,但配置繁琐
插件生态生态快速增长,支持 Rollup 插件,官方插件覆盖主流框架生态成熟丰富,插件数量多,可满足各类复杂需求
配置复杂度零配置起步,配置简洁,大部分需求可通过简单配置实现配置繁琐,需手动配置 loader、plugin,学习成本高
适用场景中小型项目、框架项目(Vue/React/Svelte)、追求开发体验的场景大型复杂项目、需要高度定制化构建流程、兼容旧项目的场景
底层技术开发时:ESM + Koa + esbuild;生产时:RollupWebpack 内核 + loader + plugin,支持多种模块格式

总结:Vite 更适合追求极致开发体验的现代前端项目,Webpack 更适合需要复杂构建逻辑的大型项目。随着 Vite 生态的完善,越来越多项目开始从 Webpack 迁移到 Vite。

八、常见问题与解决方案

8.1 开发环境跨域问题

解决方案:通过 server.proxy 配置代理,将接口请求转发到后端服务,如前文 3.2 节示例。

8.2 第三方依赖不支持 ESM

问题:部分老旧第三方依赖仅提供 CommonJS 格式,开发时可能出现解析错误。

解决方案:Vite 会自动对 node_modules 中的依赖进行预构建,转为 ESM 格式。若仍有问题,可通过 optimizeDeps.include 强制预构建指定依赖:

export default defineConfig({
  optimizeDeps: {
    include: ['some-commonjs-package'] // 强制预构建该依赖
  }
});
    

8.3 HMR 不生效

常见原因及解决方案:

  • 模块导出方式问题:避免使用 module.exports 导出,优先使用 ESM 的 export/import。
  • 自定义 HMR 逻辑冲突:检查 handleHotUpdate 钩子是否正确实现,避免阻止默认 HMR 行为。
  • 文件路径问题:确保模块路径大小写一致(Windows 系统不区分大小写,Linux/macOS 区分)。
  • 缓存问题:删除 node_modules/.vite 缓存目录,重新启动项目。

8.4 生产环境打包后页面空白

常见原因及解决方案:

  • base 配置错误:非根目录部署时,未正确设置 base 路径,导致资源加载失败。
  • 路由模式问题:Vue Router/React Router 使用 history 模式时,服务器未配置 fallback 到 index.html,导致刷新页面 404。解决方案:配置服务器(如 Nginx)将所有请求转发到 index.html。
  • 资源路径错误:检查 rollupOptions 中的 assetFileNames、chunkFileNames 配置,确保资源路径正确。

8.5 TypeScript 类型检查失效

问题:Vite 仅负责 TS 转 JS,不进行类型检查,开发时可能遗漏类型错误。

解决方案:在 package.json 中添加类型检查脚本,配合 lint-staged、husky 在提交前进行检查:


{
  "scripts": {
    "type-check": "tsc --noEmit"
  }
}
    

九、总结与展望

Vite 凭借其极致的开发体验、简洁的配置、强大的扩展性,彻底改变了前端开发的构建流程,尤其适合现代框架项目。它解决了传统构建工具的性能瓶颈,同时兼顾生产环境的打包优化,已成为前端工程化的重要选择。

未来,Vite 有望在插件生态、复杂场景支持、跨平台构建等方面持续迭代,进一步缩小与 Webpack 在复杂项目场景下的差距。对于前端开发者而言,掌握 Vite 已成为必备技能,无论是新项目搭建还是旧项目迁移,Vite 都能显著提升开发效率和项目性能。