Skip to content

BinMaker 最早的项目用 Webpack:npm run dev 启动要等 40 秒,改一个字的样式也要等它重新编译。后来接手 Vite 项目——命令一点就开,改代码保存瞬间刷新。同样写前端,开发体验差了一个数量级。这篇按「会用」的标准讲 Vite:三条命令、常用配置、生产构建,够日常开发跑通。

一、Vite 是什么:dev 时根本不用打包

老一代构建工具(Webpack)的思路是打包:把所有模块(JS、CSS、图片)分析依赖、合并压缩成一个 bundle,浏览器才能跑。项目一大,打包就要等很久。

Vite 换了个思路:dev 时根本不打包。现代浏览器原生支持 ES Module——<script type="module"> 可以直接 import 别的文件。Vite 就把源码原样发给浏览器,浏览器自己按 import 链加载:

Webpack 打包 vs Vite 原生 ESM

对比Webpack(老一代)Vite
dev 时先把全部模块打包成 bundle不打包,浏览器直接按 import 加载
启动速度等打包,项目越大越慢秒级,几乎不受项目规模影响
改代码刷新重新编译相关模块按模块热更新,改哪刷哪
生产构建打包压缩依然打包(用 Rollup)

所以 Vite 有两套链路:dev 用「原生 ESM + esbuild」主打快,build 用「Rollup」主打稳。为什么生产构建不也用 esbuild,见 Vite 为什么这么快:dev 与 build 的双引擎

二、三条命令跑起来

bash
# 1. 初始化项目(--template 指定模板,vue / react / vanilla / svelte...)
npm create vite@latest my-app -- --template vue

# 2. 装依赖
cd my-app
npm install

# 3. 开发
npm run dev      # 秒级启动,终端输出本地地址 http://localhost:5173

# 生产构建 + 预览
npm run build    # 输出到 dist/(压缩、带 hash)
npm run preview  # 本地起一个静态服务,预览 dist/ 产物

不用脚手架也能用:一个 index.html + 一个 main.js + 一个 vite.config.js,装个 vite 就开跑,适合给老页面渐进引入:

html
<!-- index.html -->
<script type="module" src="/main.js"></script>
js
// main.js —— 原生 ESM,浏览器直接加载
import { renderTable } from './table.js';
renderTable();

三、目录结构:index.html 是入口

和 Webpack 最大的不同:入口是根目录的 index.html(Webpack 是 src 里的 JS 入口),Vite 以它为起点解析整个 import 链:

my-app/
├── index.html        # 入口,script type="module" 指向 /src/main.js
├── vite.config.js    # 配置(别名、代理、插件)
├── public/           # 原样拷贝的静态文件,路径写 /xxx.png
└── src/
    ├── main.js       # 应用入口
    ├── App.vue
    └── assets/       # 会被打包处理的资源(走 import 引入)

四、常用配置三件套:别名、代理、环境变量

vite.config.jsdefineConfig 包一层(为了 IDE 提示):

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

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      // 别名:@ 指到 src,写 import 不用数 ../../ 了
      '@': path.resolve(__dirname, 'src'),
    },
  },
  server: {
    proxy: {
      // 代理:前端请求 /api 自动转发到后端,联调必备
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true, // 让后端看到的是来自它的请求,不是 localhost:5173
      },
    },
  },
});

环境变量:项目根目录放 .env / .env.development / .env.production,只有 VITE_ 前缀的变量会暴露给前端:

bash
# .env.development
VITE_API_BASE=/api
js
// 代码里读:import.meta.env.VITE_API_BASE
const base = import.meta.env.VITE_API_BASE;

三个环境(dev / build / preview)自动加载对应文件:dev 读 .env.development,build 读 .env.production,公共的放 .env为什么用 import.meta.env 而不是 process.env——因为 dev 跑在浏览器里根本没有 Node 的 processimport.meta.env 是 Vite 在编译期注入的,build 后变量值直接替换进代码。

五、静态资源:public 和 assets 怎么选

目录行为适合放
public/原样拷贝到 dist 根目录,路径写死 /logo.png不会被引用的(favicon)、要固定路径的
src/assets/走 import 引入,打包时压缩 + 加内容 hash图片、字体等代码里用到的资源

判断标准:代码里用 import 引的就是 assets(享受 hash 缓存),否则放 public。assets 加 hash 的好处是文件名变了浏览器就知道该重新下载,public 的文件永远同名、容易命中过期缓存。

六、生产构建:dist 里有什么

bash
npm run build

产物在 dist/:JS/CSS 压缩合并、文件名带内容 hash(如 index-3f2a1b.js),静态资源按类型分目录。npm run preview 可以在本地起个静态服务模拟生产环境验证产物,上线前先跑它看一眼。

总结

要记住的一句话
dev 不打包浏览器原生 ESM 加载源码,所以秒启
入口是 index.html根目录那个,不是 src 里的 JS
配置三件套alias(路径)、proxy(联调)、env(环境变量)
build 用 Rollup生产才打包,压缩 + hash
静态资源import 的走 assets,路径写死的走 public

版本提醒:Vite 本文基于 Vite 8 实测;它不绑定 Vue,React、Svelte、原生 JS 都能用,模板不同而已。Vite 的 dev server 也是 Vue 快速入门npm create vue@latest 的底层。

链式导航:想知道 Vite 为什么这么快(esbuild 预构建、HMR 原理、为什么 build 用 Rollup),看 Vite 为什么这么快:dev 与 build 的双引擎;模板语法和响应式是 Vue 快速入门 的内容;Vue 项目里状态管理用 Pinia 状态管理详解