Vite快速入门:秒级启动的开发体验

Vite快速入门:秒级启动的开发体验

Vite Logo

如果你用过Webpack,一定经历过这样的痛苦:

  • npm run dev启动要等30秒
  • 改一行代码,热更新要等3秒
  • 配置文件写得想砸键盘

Vite就是为了终结这些痛苦而生的。它的名字来自法语"快"(vite),快到让你怀疑人生。

为什么Vite这么快?

传统打包工具的问题

Webpack的工作方式:

  1. 启动时,从入口文件开始
  2. 递归分析所有依赖
  3. 打包成一个(或几个)大文件
  4. 启动开发服务器

项目越大,依赖越多,打包越慢。

Vite的革命性做法

Vite利用了浏览器的原生ES模块能力:

开发环境

  1. 启动时不打包
  2. 浏览器请求哪个文件,就编译哪个文件
  3. 源码按需编译,秒级启动

生产环境
使用Rollup打包,优化输出

graph LR
    A[浏览器请求] --> B[Vite Dev Server]
    B --> C{已编译?}
    C -->|是| D[返回缓存]
    C -->|否| E[即时编译]
    E --> D

创建第一个Vite项目

# 创建Vue3项目
npm create vite@latest my-vue-app -- --template vue

# 或者用pnpm(推荐)
pnpm create vite my-vue-app --template vue

# 进入项目
cd my-vue-app

# 安装依赖
pnpm install

# 启动开发服务器
pnpm dev

输出:

  VITE v5.1.0  ready in 234 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

234毫秒!这就是Vite的速度。

项目结构

my-vue-app/
├── index.html          # 入口HTML
├── package.json        # 项目配置
├── vite.config.js      # Vite配置
├── public/             # 静态资源(不处理)
│   └── favicon.ico
└── src/                # 源代码
    ├── main.js         # 入口文件
    ├── App.vue         # 根组件
    └── assets/         # 资源文件
        └── vue.svg

index.html

Vite把index.html作为入口,而不是main.js


    <title>Vite + Vue</title>

    <div id="app"></div>

注意type="module",这告诉浏览器用ES模块方式加载。

main.js

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

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

App.vue


import { ref } from 'vue'

const count = ref(0)

  <div>
    <h1>Vite + Vue</h1>
    <button>
      Count: {{ count }}
    </button>
  </div>

h1 {
  color: #42b883;
}

Vite配置

基础配置

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],

  // 开发服务器
  server: {
    port: 3000,          // 端口
    open: true,          // 自动打开浏览器
    host: '0.0.0.0',     // 允许局域网访问
    cors: true           // 启用CORS
  },

  // 构建配置
  build: {
    outDir: 'dist',      // 输出目录
    sourcemap: true      // 生成sourcemap
  }
})

路径别名

import { defineConfig } from 'vite'
import { fileURLToPath, URL } from 'node:url'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

使用:

import MyComponent from '@/components/MyComponent.vue'
// 而不是
import MyComponent from '../../../components/MyComponent.vue'

环境变量

# .env.development
VITE_API_URL=http://localhost:3000/api

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

使用:

const apiUrl = import.meta.env.VITE_API_URL

注意:只有VITE_前缀的变量才会暴露给客户端代码。

代理API请求

export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  }
})

CSS处理

CSS Modules


  <div>
    <h1>Hello</h1>
  </div>

.container {
  padding: 20px;
}
.title {
  color: blue;
}

预处理器

# 安装Sass
pnpm add -D sass

  <div class="container">
    <h1>Hello</h1>
  </div>

$primary-color: #42b883;

.container {
  padding: 20px;

  h1 {
    color: $primary-color;
  }
}

全局CSS

// vite.config.js
export default defineConfig({
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: <code>@import "@/styles/variables.scss";
      }
    }
  }
})

静态资源

引入方式

// 直接引入
import logo from '@/assets/logo.png'

// URL形式
const imgUrl = new URL('./assets/logo.png', import.meta.url).href

// 动态引入(Vite特有)
const modules = import.meta.glob('./assets/*.png')
// 返回: { './assets/a.png': () => import('./assets/a.png'), ... }

public目录

public/下的文件不会被处理,直接复制到输出目录:

<img src="/logo.png" />

访问:http://localhost:5173/logo.png

构建优化

代码分割

// vite.config.js
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          'vendor': ['vue', 'vue-router', 'pinia'],
          'ui': ['element-plus']
        }
      }
    }
  }
})

分析打包大小

pnpm add -D rollup-plugin-visualizer
import { visualizer } from 'rollup-plugin-visualizer'

export default defineConfig({
  plugins: [
    vue(),
    visualizer({ open: true })
  ]
})

构建后会生成一个HTML文件,可视化显示每个模块的大小。

TypeScript支持

# 创建TS项目
pnpm create vite my-app --template vue-ts

Vite原生支持TypeScript,无需额外配置(但需要vue-tsc做类型检查)。

pnpm add -D vue-tsc
// package.json
{
  "scripts": {
    "build": "vue-tsc && vite build"
  }
}

常用插件

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'           // JSX支持
import vueDevTools from 'vite-plugin-vue-devtools'   // Vue DevTools
import compression from 'vite-plugin-compression'    // Gzip压缩
import { visualizer } from 'rollup-plugin-visualizer'

export default defineConfig({
  plugins: [
    vue(),
    vueJsx(),
    vueDevTools(),
    compression(),
    visualizer()
  ]
})

常见问题

Q: 为什么生产构建用Rollup?

A: Rollup生成的代码更干净、更小。开发时用原生ES模块追求速度,生产时用Rollup追求优化。

Q: 如何处理CommonJS模块?

A: Vite会自动转换,大多数情况无需处理。如果有问题:

export default defineConfig({
  optimizeDeps: {
    include: ['some-cjs-module']
  }
})

Q: 热更新不生效?

A: 检查文件是否被正确引入,确保没有语法错误。可以在浏览器控制台查看HMR状态。

Vite vs Webpack

特性 Vite Webpack
启动速度 ⚡ 秒级 🐢 项目大时慢
热更新 ⚡ 毫秒级 🐢 较慢
配置复杂度 📝 极简 😵 复杂
生态成熟度 🌱 快速发展 🌳 非常成熟
生产打包 Rollup Webpack

结论:新项目首选Vite,除非必须用Webpack生态的特定插件。

小结

你现在掌握了:

  • Vite为什么快(原生ES模块)
  • 创建和配置Vite项目
  • 路径别名、环境变量、代理
  • CSS处理(Modules、预处理器)
  • 静态资源引入
  • 构建优化技巧

下一期,我们正式进入Vue3基础。你会学到Vue3的核心概念:响应式、组件、模板语法。


练习任务

  1. 创建一个Vite + Vue3项目
  2. 配置@路径别名
  3. 配置开发服务器代理
  4. 使用Sass编写样式

下期预告:《Vue3基础:响应式系统和组件入门》—— ref和reactive怎么选?组件怎么通信?

Views: 1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Index