Featured image of post Vue 3 + TypeScript + Vite 脚手架与工程化实战

Vue 3 + TypeScript + Vite 脚手架与工程化实战

从 npm create vite@latest 走通 Vue 3 + TS 项目初始化,到 VSCode 插件、代码片段、tsconfig 路径别名、vite.config.ts 别名 + 代理 + 端口、ESLint + Prettier 全套、多环境变量(.env.dev/.env.test/.env.prod)、路由 / Pinia / Axios / 进度条等工程化配置。

为什么写这篇:2023 年 Vue 3 + Vite + TypeScript 已经是新项目"标准三件套"。本文走通从 npm create vite 到生产环境打包的完整流程,把代码片段 / ESLint / Prettier / 路径别名 / 多环境变量 / 代理一次性配齐。

适用读者:Vue 3 初学者;从 Vue 2 迁过来的工程师;想用 Vite 替代 Webpack 的项目负责人。

前置知识:会用 npm;了解 Vue / TypeScript 基础。

目录

  1. 环境要求
  2. 两种创建项目方式
  3. 项目目录结构
  4. IDE 工具与 VSCode 插件
  5. 代码片段配置
  6. Vite 配置:路径别名 + 代理 + 端口
  7. 代码风格:ESLint + Prettier
  8. 多环境变量配置
  9. 常见工程化依赖
  10. TS2307 找不到 .vue 类型

1. 环境要求

工具版本备注
Node.js20.12.0+(推荐 LTS)Vite 5 要求 Node 18+ 或 20+
npm10+Node 自带
pnpm8+(推荐)装包快、磁盘省
Vite5.3+本文以 Vite 5 为准
VSCode最新版装 Vue 官方插件

Vite 7(2025 推出) 要求 Node 20.19+ 或 22.12+。

1
2
3
node -v     # v20.12.0
npm -v      # 10.x
pnpm -v     # 8.x

2. 两种创建项目方式

方式一:npm create vite@latest(推荐)

1
npm create vite@latest

交互式:

1
2
3
4
5
✔ Project name: … vue3-ts-demo
✔ Select a framework: › Vue
✔ Select a variant: › TypeScript
✔ Use rolldown-vite (Experimental)?: no   # 实验性质,暂不用
✔ Install with pnpm and start now?: yes

完成后 Vite 自动启动:

1
2
3
4
5
  VITE v5.3.5  ready in 339 ms

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

Rolldown-Vite:Vite 团队基于 Rust 的下一代打包器,目前实验阶段。生产环境建议关闭。

方式二:npm init vue@latest(Vue 官方脚手架)

1
npm init vue@latest
1
2
3
4
5
6
7
8
9
✔ Project name: … iip-frontend
✔ Add TypeScript? Yes
✔ Add JSX Support? No
✔ Add Vue Router? Yes
✔ Add Pinia? Yes
✔ Add Vitest? No
✔ Add an End-to-End Testing Solution? No
✔ Add ESLint? Yes
✔ Add Prettier? Yes

区别

  • create-vite 极简,只有 Vue + TS
  • create-vue 是 Vue 官方脚手架,可选 Router/Pinia/测试/格式化

完成后:

1
2
3
4
5
6
7
8
cd iip-frontend
npm install
npm run format    # Prettier 全量格式化
npm run dev

git init && git add -A && git commit -m "init"
git remote add origin <YOUR_REPO_URL>
git push -u origin master

3. 项目目录结构

 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
vue3-ts-demo/
├── dist/                      # 构建产物
├── node_modules/
├── public/                    # 不参与构建的静态资源
│   └── vite.svg
├── src/
│   ├── assets/                # 静态资源(图片、字体)
│   ├── components/            # 公共组件
│   │   └── HelloWorld.vue
│   ├── router/                # vue-router 配置(若用 create-vue)
│   ├── stores/                # Pinia 状态
│   ├── views/                 # 页面级组件
│   ├── App.vue                # 根组件
│   ├── main.ts                # 入口
│   ├── env.d.ts               # 环境变量类型
│   └── vite-env.d.ts          # Vite 内置类型
├── .env.development           # 开发环境变量
├── .env.production            # 生产环境变量
├── .eslintrc.cjs              # ESLint 配置
├── .prettierrc.json           # Prettier 配置
├── .gitignore
├── index.html                 # 入口 HTML
├── package.json
├── pnpm-lock.yaml             # 必须提交
├── README.md
├── tsconfig.json              # TS 根配置(references)
├── tsconfig.app.json          # 应用代码 TS 配置
├── tsconfig.node.json         # Node 环境 TS 配置
└── vite.config.ts             # Vite 配置

tsconfig 的 references:Vite 模板默认拆成 tsconfig.app.json(业务代码)和 tsconfig.node.json(Vite 配置),用 references 关联。


4. IDE 工具与 VSCode 插件

4.1 必装插件

插件用途
VolarVue 3 + TS 官方语言服务(替代 Vetur)
TypeScript Vue Plugin (Volar)TS 侧的 .vue 类型支持
ESLint代码检查
Prettier格式化
EditorConfig for VS Code跨编辑器风格
Auto Rename TagHTML 标签自动改名
Path Intellisense路径补全
Vue 3 Snippets代码片段

4.2 禁用 Vue 2 插件

如果之前装过 Vetur(Vue 2 时代的官方插件),必须禁用或卸载——它和 Volar 冲突,类型推断会乱。


5. 代码片段配置

.vscode/vue3.code-snippets

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "Print to console": {
    "prefix": "vue3",
    "body": [
      "<!-- ${1:new page} -->",
      "<!-- @author: ${2:lwd} -->",
      "<!-- @since: ${CURRENT_YEAR}-${CURRENT_MONTH}-${CURRENT_DATE} -->",
      "<!-- ${TM_FILENAME} -->",
      "<template>",
      "  <div></div>",
      "</template>",
      "",
      "<script setup lang=\"ts\">",
      "</script>",
      "",
      "<style scoped>",
      "</style>"
    ],
    "description": "Vue 3 + TS 单文件组件模板"
  }
}

输入 vue3 + Tab 即可生成 SFC 三段式骨架。


6. Vite 配置:路径别名 + 代理 + 端口

6.1 装 Node 类型声明

1
npm i @types/node -D

让 TS 知道 path.resolveprocess.env 等 Node API。

6.2 tsconfig.node.json 加 types

1
2
3
4
5
6
7
{
  "compilerOptions": {
    "types": ["node"],
    "composite": true
  },
  "include": ["vite.config.ts"]
}

6.3 vite.config.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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import * as path from 'path'

// https://vite.dev/config/
export default defineConfig({
  resolve: {
    // 路径别名
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  },

  plugins: [vue()],

  server: {
    port: 8080,                          // 启动端口
    host: '127.0.0.1',                   // 监听地址
    open: true,                          // 自动打开浏览器
    hmr: {
      host: '127.0.0.1',
      port: 8080
    },
    // 反向代理
    proxy: {
      '/api': {
        target: 'https://your-backend.example.com',
        changeOrigin: true,
        rewrite: (path: string) => path.replace(/^\/api/, '')
      }
    }
  },

  // 生产构建
  build: {
    target: 'es2020',
    sourcemap: false,
    rollupOptions: {
      output: {
        manualChunks: {
          // 把第三方库拆成单独 chunk
          vue: ['vue', 'vue-router', 'pinia'],
          echarts: ['echarts']
        }
      }
    }
  }
})

tsconfig.json 也要加别名(不然 TS 找不到 @/components/...):

1
2
3
4
5
6
7
8
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

7. 代码风格:ESLint + Prettier

7.1 装依赖

1
npm i -D eslint eslint-plugin-vue @typescript-eslint/parser @typescript-eslint/eslint-plugin

7.2 .eslintrc.cjs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
module.exports = {
  root: true,
  parser: 'vue-eslint-parser',

  parserOptions: {
    parser: '@typescript-eslint/parser',
    ecmaVersion: 2020,
    sourceType: 'module',
    ecmaFeatures: { jsx: true }
  },

  extends: [
    'plugin:vue/vue3-recommended',
    'plugin:@typescript-eslint/recommended'
  ],

  rules: {
    // 自定义规则...
  }
}

7.3 .eslintignore

1
2
3
node_modules/
dist/
index.html

7.4 package.json scripts

1
2
3
4
5
{
  "scripts": {
    "eslint": "eslint --ext .js,.ts,.vue --ignore-path .gitignore --fix src"
  }
}

7.5 Prettier

1
npm i -D prettier eslint-config-prettier eslint-plugin-prettier

.prettierrc.cjs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
module.exports = {
  printWidth: 80,
  tabWidth: 2,
  useTabs: false,
  semi: false,                 // Vue 风格无分号
  singleQuote: true,
  quoteProps: 'as-needed',
  trailingComma: 'all',
  bracketSpacing: true,
  arrowParens: 'always',
  endOfLine: 'auto'
}

.eslintrc.cjs extends 末尾加 'plugin:prettier/recommended'(关掉与 prettier 冲突的规则)。

7.6 VSCode 保存自动格式化

.vscode/settings.json

1
2
3
4
5
6
7
8
9
{
  "editor.formatOnSave": true,
  "[javascript]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  },
  "[vue]": {
    "editor.defaultFormatter": "Vue.volar"
  }
}

8. 多环境变量配置

Vite 默认只有 developmentproduction 两套环境。要多套(如 dev / test / staging / prod),自己建文件:

1
2
3
4
.env                # 所有环境都加载
.env.development    # npm run dev 加载
.env.test           # npm run build:test 加载
.env.production     # npm run build:prod 加载

8.1 .env.development

1
2
3
4
# 必须 VITE_ 开头才能被 import.meta.env 识别
VITE_ENV = 'development'
VITE_APP_BASE_API = '/api'
VITE_APP_TITLE = '开发环境'

8.2 .env.production

1
2
3
VITE_ENV = 'production'
VITE_APP_BASE_API = 'https://api.example.com'
VITE_APP_TITLE = '生产环境'

8.3 package.json scripts

1
2
3
4
5
6
7
8
9
{
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc -b && vite build",
    "build:test": "tsc --noEmit && vite build --mode test",
    "build:prod": "tsc --noEmit && vite build --mode production",
    "preview": "vite preview"
  }
}

8.4 代码里读环境变量

1
2
console.log(import.meta.env.VITE_APP_BASE_API)
console.log(import.meta.env.VITE_ENV)

注意

  • 自定义变量必须 VITE_ 开头(防止意外暴露服务端配置)
  • import.meta.env 是 Vite 注入的,不在 process.env

9. 常见工程化依赖

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 路由
pnpm add vue-router@4

# 状态管理
pnpm add pinia pinia-plugin-persist    # 后者是持久化插件

# HTTP
pnpm add axios
pnpm add nprogress                     # 顶部进度条
pnpm add @types/nprogress -D

# UI 库
pnpm add element-plus @element-plus/icons-vue

# 工具
pnpm add dayjs lodash
pnpm add @types/lodash -D

9.1 Pinia 持久化示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// store/user.ts
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    token: '',
    name: ''
  }),
  actions: {
    setToken(token: string) {
      this.token = token
    }
  },
  persist: {
    key: 'user-store',
    storage: localStorage
  }
})

9.2 Axios 封装示例

 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
// utils/http.ts
import axios from 'axios'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'

NProgress.configure({ showSpinner: false })

const http = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 15000
})

http.interceptors.request.use(config => {
  NProgress.start()
  const token = localStorage.getItem('token')
  if (token) {
    config.headers.Authorization = `Bearer ${token}`
  }
  return config
})

http.interceptors.response.use(
  response => {
    NProgress.done()
    return response.data
  },
  error => {
    NProgress.done()
    return Promise.reject(error)
  }
)

export default http

10. TS2307 找不到 .vue 类型

错误信息:

1
error TS2307: Cannot find module './App.vue' or its corresponding type declarations.

解法:建 src/vite-env.d.ts(Vite 模板已自动生成):

1
2
3
4
5
6
7
/// <reference types="vite/client" />

declare module '*.vue' {
  import type { DefineComponent } from 'vue'
  const component: DefineComponent<{}, {}, any>
  export default component
}

Why.vue 不是原生模块,需要 TS 知道它的"形状"。DefineComponent 是 Vue 3 提供的 SFC 类型。


小结

Vue 3 + Vite + TS 工程化核心要点:

  1. 创建npm create vite@latest 选 Vue + TS 模板,30 秒跑通 demo
  2. 目录:用 src/viewssrc/componentssrc/routersrc/stores 标准化
  3. 配置vite.config.ts 配 alias / proxy / port,tsconfig.json 配 paths
  4. 代码风格:ESLint + Prettier 双管齐下,保存自动格式化
  5. 环境变量VITE_ 前缀 + 多文件(.env.development / .env.production)
  6. HTTP:Axios 拦截器 + NProgress 进度条 + 401 自动跳登录

下一步:学 Vue 3 专属特性——Composition API、<script setup>、Pinia 持久化、Suspense、<Teleport>、Volar 类型推断、Vitest 单元测试。Vue 3 + Vite 是 2024+ 的新项目默认选择

参考资料

使用 Hugo 构建
主题 StackJimmy 设计