从零搭建 Vite + Vue3 工程化项目

2025-05-18
Vue

本文是 Vite 系列第一篇。Vite 凭借极快的冷启动按需编译,已经成为 Vue3 生态的默认构建工具。本文带你从零搭建一套可上生产环境的 Vue3 工程,涵盖工程结构、路径别名、环境变量、代码规范与多环境打包。

一、为什么从 vue-cli 迁移到 Vite

vue-cli(Webpack) 在启动大型项目时,需要把整个应用打包成 bundle 才能提供开发服务,随着依赖增多,启动和热更新(HMR)会越来越慢,甚至出现”启动等半分钟、改一行热更新等 3 秒”的痛点。

Vite 的核心思路是按需编译

  • 开发阶段:利用浏览器原生 ESM,源码直接以模块方式提供给浏览器,无需打包,启动即秒开;改动哪个文件就编译哪个文件,HMR 接近毫秒级。
  • 生产阶段:仍然用 Rollup 打包,保证产物体积与 Tree-Shaking。

一句话总结:开发用原生 ESM 快跑,构建用 Rollup 优化

二、初始化项目

# 使用官方脚手架(推荐)
npm create vite@latest my-project -- --template vue-ts

# 或使用 create-vue(官方 Vue 全家桶模板,含路由/Pinia/ESLint 可选)
npm create vue@latest my-project

vue-ts 模板为例,生成的核心结构如下:

my-project
├── index.html          # 入口 HTML(Vite 的入口是 index.html 而非 src/main.js)
├── vite.config.ts      # Vite 配置
├── tsconfig.json
├── src
│   ├── main.ts         # 应用入口
│   ├── App.vue
│   ├── components/
│   ├── views/          # 路由页面
│   ├── router/
│   ├── stores/         # Pinia
│   └── assets/
└── package.json

注意:Vite 以 index.html 作为入口,通过 <script type="module" src="/src/main.ts"> 引入应用,这是与 Webpack 最大的区别。

三、配置路径别名

开发中我们常用 @ 指代 src,避免到处写 ../../。需要在 vite.config.tstsconfig.json 两处配置:

// vite.config.ts
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
      // 组件库样式别名
      // '@styles': fileURLToPath(new URL('./src/styles', import.meta.url)),
    },
  },
  plugins: [vue()],
})
// tsconfig.json —— 让 TS 也能识别别名,否则编辑器会报错
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

四、环境变量与多环境构建

vue-cli.env.development / .env.production,Vite 的约定是 .env.env.development.env.production.env.staging 等,优先级:具体模式 > development/production > .env

# .env.development
VITE_APP_TITLE=开发环境
VITE_API_BASE_URL=/api

# .env.production
VITE_APP_TITLE=生产环境
VITE_API_BASE_URL=https://api.example.com

只有以 VITE_ 开头的变量才会暴露给前端代码,通过 import.meta.env 访问:

// 业务代码中使用
const baseURL = import.meta.env.VITE_API_BASE_URL

// 自定义类型提示(env.d.ts)
interface ImportMetaEnv {
  readonly VITE_API_BASE_URL: string
  readonly VITE_APP_TITLE: string
}

构建不同环境:

npm run build                      # 等价 vite build,加载 .env.production
npm run build:staging -- --mode staging   # 指定 --mode staging

这里有个非常实用的技巧:给 package.json 增加 build:staging,配合 --mode 就能一套代码打多套环境,对应我之前写的《vue-cli3 多环境打包配置》,Vite 的方式更简洁。

五、代码规范:ESLint + Prettier

工程化项目必须统一代码风格,防止”一人一个格式”。

npm install -D eslint prettier eslint-plugin-vue \
  @vue/eslint-config-typescript @vue/eslint-config-prettier

配置 eslint.config.js(新版扁平配置):

// eslint.config.js
import pluginVue from 'eslint-plugin-vue'
import vueTsEslintConfig from '@vue/eslint-config-typescript'
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'

export default [
  {
    name: 'app/files-to-lint',
    files: ['**/*.{ts,mts,tsx,vue}'],
  },
  {
    name: 'app/files-to-ignore',
    ignores: ['**/dist/**', '**/coverage/**'],
  },
  ...pluginVue.configs['flat/essential'],
  ...vueTsEslintConfig(),
  skipFormatting,
]

并在 package.json 中加入脚本:

{
  "scripts": {
    "lint": "eslint . --fix",
    "format": "prettier --write src/"
  }
}

配合 VS Code 的 ESLint + Prettier 插件,保存时自动格式化,提交前 npm run lint 兜底。

六、生产构建与体积分析

# 构建产物
npm run build

# 体积分析(推荐 vite-plugin-visualizer)
npm install -D vite-plugin-visualizer
// vite.config.ts
import { visualizer } from 'vite-plugin-visualizer'

export default defineConfig({
  plugins: [visualizer({ open: true })],
  build: {
    // 手动分包,避免第三方库都塞进一个 vendor 里
    rollupOptions: {
      output: {
        manualChunks: {
          vue: ['vue', 'vue-router', 'pinia'],
          echarts: ['echarts'],
        },
      },
    },
    // 关闭或调低 sourcemap 以减小体积
    sourcemap: false,
  },
})

七、小结

Vite 并不只是”更快”,它把开发体验提升到了新的高度。对面试而言,能讲清楚”Vite 为什么快”(ESM 按需编译 vs Webpack 全量打包)、”开发/生产双引擎”(Esbuild + Rollup)以及工程化规范,就是很有分量的加分项。

下一篇预告:《TypeScript 核心类型系统精讲与 Vue3 实战》。


Similar Posts

Content