前言
Vue 3 是目前最流行的前端框架之一,而 Vite 作为新一代前端构建工具,凭借其极速冷启动和热更新能力,已逐渐取代 Vue CLI 成为 Vue 生态的主流选择。本文将详细介绍在 Windows 和 Linux 环境下从零搭建 Vue 3 + Vite 开发环境的完整流程。
一、环境准备
1.1 Node.js 安装
Vite 要求 Node.js 版本 >= 18.x。推荐使用 nvm(Node Version Manager)来管理 Node.js 版本。
Windows 安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
nvm install 22.14.0
nvm use 22.14.0
node --version npm --version
|
Linux 安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
source ~/.bashrc
nvm install 22.14.0 nvm use 22.14.0 nvm alias default 22.14.0
node --version npm --version
|
1.2 包管理器选择
推荐使用 pnpm(性能更优、磁盘空间利用率更高):
1 2 3 4 5 6 7 8
| npm install -g pnpm
pnpm --version
pnpm config set registry https://registry.npmmirror.com
|
npm 和 yarn 也是常用选择。三种包管理器特性对比如下:
| 特性 | npm | yarn | pnpm |
| 安装速度 | 较慢 | 快 | 最快 |
| 磁盘空间 | 重复存储 | 重复存储 | 硬链接共享 |
| monorepo 支持 | workspaces | workspaces | 内置支持 |
| 严格模式 | 否 | 否 | 是(杜绝幽灵依赖) |
| lock 文件 | package-lock.json | yarn.lock | pnpm-lock.yaml |
二、创建 Vue 3 + Vite 项目
2.1 使用 create-vue 脚手架
create-vue 是 Vue 官方推荐的脚手架工具,基于 Vite 构建:
1 2 3 4 5
| npm create vue@latest
pnpm create vue@latest
|
执行后会进入交互式配置界面:
1 2 3 4 5 6 7 8 9 10
| ✔ Project name: … my-vue-app ✔ Add TypeScript? … Yes ✔ Add JSX Support? … Yes ✔ Add Vue Router for Single Page Application development? … Yes ✔ Add Pinia for state management? … Yes ✔ Add Vitest for Unit Testing? … Yes ✔ Add an End-to-End Testing Solution? › Playwright ✔ Add ESLint for code quality? … Yes ✔ Add Prettier for code formatting? … Yes ✔ Add Vue DevTools 7 for Vue debugging? … Yes
|
配置完成后:
1 2 3 4 5 6 7 8
| cd my-vue-app
pnpm install
pnpm dev
|
2.2 手动搭建(更深入理解项目结构)
如果希望更灵活地控制配置,也可以手动搭建:
1 2 3 4 5 6 7 8 9
| mkdir my-vue-app && cd my-vue-app
pnpm init
pnpm add vue@latest vue-router@latest pinia@latest pnpm add -D vite @vitejs/plugin-vue typescript vue-tsc
|
创建基础文件结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| my-vue-app/ ├── index.html ├── vite.config.ts ├── tsconfig.json ├── tsconfig.app.json ├── tsconfig.node.json ├── package.json ├── public/ │ └── favicon.ico ├── src/ │ ├── main.ts │ ├── App.vue │ ├── env.d.ts │ ├── assets/ │ │ └── main.css │ ├── components/ │ │ └── HelloWorld.vue │ ├── router/ │ │ └── index.ts │ ├── stores/ │ │ └── counter.ts │ └── views/ │ ├── Home.vue │ └── About.vue
|
index.html — Vite 的入口文件(不在 src 目录内):
1 2 3 4 5 6 7 8 9 10 11 12 13
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vue 3 + Vite App</title> </head> <body> <div id="app"></div> <script type="module" src="/src/main.ts"></script> </body> </html>
|
vite.config.ts — Vite 核心配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import vueDevTools from 'vite-plugin-vue-devtools'
export default defineConfig({ plugins: [ vue(), vueDevTools(), ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } }, server: { port: 5173, host: true, open: true, proxy: { '/api': { target: 'http://localhost:3000', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') } } }, build: { outDir: 'dist', sourcemap: false, chunkSizeWarningLimit: 500 } })
|
src/main.ts — 应用入口:
1 2 3 4 5 6 7 8 9 10
| import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' import router from './router' import './assets/main.css'
const app = createApp(App) app.use(createPinia()) app.use(router) app.mount('#app')
|
src/App.vue — 根组件:
1 2 3 4 5 6 7 8 9 10 11 12 13
| <script setup lang="ts"> import { RouterLink, RouterView } from 'vue-router' </script>
<template> <header> <nav> <RouterLink to="/">首页</RouterLink> <RouterLink to="/about">关于</RouterLink> </nav> </header> <RouterView /> </template>
|
2.3 生成的项目结构说明
| 文件/目录 | 作用 |
| index.html | Vite 入口 HTML 文件(不在 src 内) |
| vite.config.ts | Vite 构建配置(别名、代理、插件) |
| tsconfig.json | TypeScript 主配置(引用 app/node 子配置) |
| src/main.ts | Vue 应用入口,创建并挂载 App |
| src/App.vue | 根组件,定义路由出口和全局布局 |
| src/router/index.ts | Vue Router 路由配置 |
| src/stores/ | Pinia 状态管理 |
| src/views/ | 页面级组件 |
| src/components/ | 可复用组件 |
| src/assets/ | 静态资源(CSS、图片等) |
| env.d.ts | TypeScript 环境声明 |
三、编辑器配置
3.1 VS Code 配置
推荐安装以下扩展:
- Vue - Official(原 Volar):Vue 3 的官方语言支持,提供模板语法高亮、类型检查、自动补全
- TypeScript Vue Plugin (Volar):在 TS 文件中获得 Vue 类型支持
- Prettier - Code formatter:代码格式化
- ESLint:代码质量检查
- Tailwind CSS IntelliSense(如果使用 Tailwind)
VS Code 工作区配置(.vscode/settings.json):
1 2 3 4 5 6 7 8 9 10 11 12
| { "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, "typescript.tsdk": "node_modules/typescript/lib", "vue.server.hybridMode": true, "[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" } }
|
3.2 代码规范化配置
Prettier(.prettierrc.json):
1 2 3 4 5 6 7 8
| { "semi": false, "singleQuote": true, "tabWidth": 2, "trailingComma": "all", "printWidth": 100, "arrowParens": "always" }
|
.eslintrc.cjs(Vue 3 + TypeScript):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = { root: true, extends: [ 'plugin:vue/vue3-essential', 'eslint:recommended', '@vue/eslint-config-typescript', '@vue/eslint-config-prettier/skip-formatting' ], parserOptions: { ecmaVersion: 'latest' }, rules: { 'vue/multi-word-component-names': 'off' } }
|
四、常用工具集成
4.1 样式方案
Tailwind CSS 集成:
1
| pnpm add -D tailwindcss @tailwindcss/vite
|
1 2 3 4 5 6 7 8 9
| import tailwindcss from '@tailwindcss/vite'
export default defineConfig({ plugins: [ tailwindcss(), vue(), ], })
|
SCSS 集成(直接安装即可,Vite 原生支持):
4.2 API 请求
封装示例(src/utils/request.ts):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import axios from 'axios'
const request = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL, timeout: 10000, headers: { 'Content-Type': 'application/json' } })
request.interceptors.request.use((config) => { const token = localStorage.getItem('token') if (token) { config.headers.Authorization = `Bearer ${token}` } return config })
request.interceptors.response.use( (response) => response.data, (error) => { if (error.response?.status === 401) { } return Promise.reject(error) } )
export default request
|
4.3 组件库
常用 Vue 3 组件库:
| 组件库 | 特点 | 安装命令 |
| Element Plus | 企业级后台,组件丰富,中文文档完善 | pnpm add element-plus |
| Naive UI | TypeScript 优先,按需加载,主题可定制 | pnpm add naive-ui |
| Ant Design Vue | Ant Design 风格,适合中后台 | pnpm add ant-design-vue |
| Vant | 移动端 UI,轻量高效 | pnpm add vant |
| PrimeVue | 国际化的全面组件集 | pnpm add primevue |
4.4 环境变量
Vite 使用 import.meta.env 访问环境变量,变量必须以 VITE_ 开头:
1 2 3 4 5 6 7
| VITE_API_BASE_URL=http://localhost:3000/api VITE_APP_TITLE=Dev App
VITE_API_BASE_URL=https://api.example.com VITE_APP_TITLE=My App
|
在组件中使用:
1 2 3
| const apiUrl = import.meta.env.VITE_API_BASE_URL const isDev = import.meta.env.DEV const isProd = import.meta.env.PROD
|
五、常见问题排查
| 问题 | 原因 | 解决方法 |
| 启动报 EACCES 错误 | 端口被占用 | 修改 vite.config.ts 中的 server.port 或 kill 占用进程 |
| 导入 .vue 文件 TS 报错 | 缺少类型声明 | 确保 env.d.ts 包含 `/// reference types="vite/client" />` |
| 代理不生效 | 路径匹配或 rewrite 配置错误 | 检查 vite.config.ts 中 server.proxy 配置 |
| 生产构建体积过大 | 未做代码分割 | 配置 build.rollupOptions.output.manualChunks |
| 热更新不生效 | 文件系统监听问题 | WSL2 下将项目放在 Linux 文件系统中 |
| pnpm 幽灵依赖问题 | 使用了未声明的间接依赖 | 在 package.json 中显式添加或设置 shamefully-hoist=true |
六、生产环境构建与部署
1 2 3 4 5
| pnpm build
pnpm preview
|
构建产物默认输出到 dist/ 目录,可直接部署到 Nginx、Vercel、Netlify 等平台。
Nginx 部署配置示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| server { listen 80; server_name your-domain.com;
root /var/www/my-vue-app/dist; index index.html;
location / { try_files $uri $uri/ /index.html; }
location /assets { expires 1y; add_header Cache-Control "public, immutable"; }
location /api { proxy_pass http://localhost:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }
|
七、最佳实践总结
- 使用 pnpm 替代 npm,安装更快且节省磁盘空间
- 配置路径别名
@ 指向 src/,避免深层相对路径
- 严格区分环境变量,使用
.env.development / .env.production
- 开启 ESLint + Prettier,在保存时自动格式化
- 合理使用路由懒加载,通过
() => import('@/views/xxx.vue') 分割代码
- TypeScript 优先,利用类型系统提高代码质量
- 使用 Composition API(
<script setup>)替代 Options API
- 生产环境关闭 source map 并启用 gzip/brotli 压缩
本文由AI辅助生成,内容仅供参考