Vue3 零基础每日笔记(040):Vite 创建 Vue3 + TS 项目——企业标配从这一篇开始

一、前言

进入 TypeScript 阶段。前面 39 篇全用 JS 是为了降低门槛,但企业项目的新建 Vue3 项目基本都选 TS ------从这篇起,代码切换到 <script setup lang="ts">,前面学的所有知识不需要重学,只是"穿上类型这件防护服"。本篇从零建一个 Vue3 + TS 工程,讲清目录变化和 tsconfig 关键项。

二、创建项目:一行命令 + 问卷

bash 复制代码
npm create vue@latest my-vue-app

这是官方脚手架 create-vue(底层就是 Vite),回车后出现问卷:

text 复制代码
✔ Project name: ... my-vue-app
✔ Add TypeScript? ... 是          ← 本篇主角,必须选
✔ Add JSX Support? ... 否
✔ Add Vue Router? ... 否          ← 路由篇再选,先手动学
✔ Add Pinia? ... 否               ← Pinia 篇再选
✔ Add Vitest / E2E / ESLint / Prettier ... 按需,新手可全否

小贴士:赶时间的同学可以 TS + Router + Pinia 全选直接生成企业骨架;但为了学习效果,建议只选 TS,Router 和 Pinia 后面篇目手动装一遍,知其所以然。

bash 复制代码
cd my-vue-app
npm install
npm run dev

三、目录变化:和 JS 版差在哪

text 复制代码
my-vue-app/
├── src/
│   ├── main.ts              ← main.js 变成了 main.ts
│   ├── App.vue
│   ├── components/
│   │   └── HelloWorld.vue   ← script 标签多了 lang="ts"
│   └── assets/
├── env.d.ts                 ← 新增!告诉 TS 那些"非 TS 文件"是什么
├── index.html
├── package.json
├── tsconfig.json            ← 新增!TS 总配置(可能引用下面两个)
│   ├── tsconfig.app.json    ← 新增!管 src 源码的编译选项
│   └── tsconfig.node.json   ← 新增!管 vite.config.ts 的编译选项
└── vite.config.ts           ← vite.config.js 也变 TS 了

三个新文件各自干什么:

  • env.d.ts :内容是 /// <reference types="vite/client" />,让 TS 认识 import.meta.env 等 Vite 特性。旧版模板它可能在 src 下,位置随版本略有不同,功能一致
  • tsconfig.json:总入口,用"引用"把配置拆给 app/node 两份------源码一套规则、配置文件一套规则,互不干扰
  • tsconfig.app.json你以后改的主要是它(比如配 @ 别名)

.vue 文件 TS 怎么认识?靠 Volar (插件全名 Vue - Official,003 篇装过)+ vue-tsc 组合:编辑器类型提示靠 Volar,命令行类型检查靠 vue-tsc。

四、type-check:Vite 不检查类型,vue-tsc 才查

看 package.json 的 scripts:

json 复制代码
{
  "scripts": {
    "dev": "vite",
    "type-check": "vue-tsc --build",
    "build": "run-p type-check \"build-only {@}\"",
    "preview": "vite preview"
  }
}

一个必须建立的心智npm run devvite build 都不做类型检查(Vite 用 esbuild 转译 TS,只剥掉类型不校验)。真正的类型关卡是:

  • 开发时:VS Code 里 Volar 的红色波浪线(编辑器实时提示)
  • 构建时:npm run build 会先跑 type-check(vue-tsc),类型不过直接构建失败

所以"明明 dev 能跑,build 却报错"不是玄学------dev 根本没查类型。

五、tsconfig 关键项速览

打开 tsconfig.app.json,重点认识这几项(脚手架已配好,会看就行):

jsonc 复制代码
{
  "compilerOptions": {
    "target": "ES2020",            // 编译目标的 JS 版本
    "module": "ESNext",
    "moduleResolution": "bundler", // 按打包器方式解析模块(Vite 专用,别改成 node)
    "strict": true,                // ★ 严格模式全家桶,报错多但护你周全,别关
    "noUnusedLocals": true,        // 未使用的变量报错
    "noUnusedParameters": true,    // 未使用的参数报错
    "skipLibCheck": true,          // 跳过 node_modules 里的类型检查(提速)
    "jsx": "preserve",
    "baseUrl": ".",
    "paths": { "@/*": ["./src/*"] } // ★ @ 别名的 TS 侧配置
  },
  "include": ["src/**/*.ts", "src/**/*.vue"]
}

记忆优先级:strict 别动、paths 配别名、moduleResolution 保持 bundler,其余用到再查。

六、配置 @ 别名:TS 侧和 Vite 侧都要配

JS 阶段(003 篇)配过 Vite 侧的别名,TS 项目要两边一起配,缺一边就一边红:

1. Vite 侧(vite.config.ts)------管"构建时路径能不能找到":

ts 复制代码
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

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

2. TS 侧(tsconfig.app.json)------管"编辑器里 import 会不会红线":

jsonc 复制代码
{
  "compilerOptions": {
    // ...其他选项
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

配完重启编辑器的 TS 服务(VS Code:Ctrl+Shift+P → Restart TS Server / 重启 TS 服务器),import xxx from '@/components/Xxx.vue' 两边都绿。

七、第一个 TS 组件:感受一下类型的存在

vue 复制代码
<!-- src/components/HelloTs.vue -->
<template>
  <p>用户:{{ user.name }},年龄:{{ user.age }}</p>
  <p>列表共 {{ list.length }} 项</p>
</template>

<script setup lang="ts">
// 注意 script 标签:lang="ts" 从此常驻
import { ref, reactive } from 'vue'

// 接口:描述数据长什么样
interface User {
  name: string
  age: number
}

const user = reactive<User>({ name: '小明', age: 18 })

// ref 会自动推断类型:list 被推断为 Ref<string[]>
const list = ref(['Vue', 'TS'])

// ❌ 试试点开注释,编辑器立刻红线(dev 仍能跑,但类型不过关)
// user.age = '十八'
</script>

user.age = '十八' 的注释打开:页面照常运行 (dev 不查类型),但编辑器红线、build 失败------这就是 TS 的价值:把运行时才炸的 bug 提前到写代码的那一刻。类型语法的详细规则下一篇展开。

【截图位置:user.age 赋值字符串时编辑器红线的截图】

八、踩坑记录

  1. 报"找不到模块 './App.vue'" :老教程让你手写 declare module '*.vue'------新版脚手架 + Volar 不需要;出现该报错先重启 TS 服务,再检查 Volar 插件是否装了官方版(Vue - Official,旧名 Volar)
  2. @ 别名一边绿一边红:只配了 vite.config 或只配了 tsconfig------必须两侧同配(第六节)
  3. tsconfig 里加错文件:paths 加到了 tsconfig.node.json(那是给 vite.config.ts 用的)------源码别名加在 tsconfig.app.json
  4. build 报类型错误但 dev 正常 :第四节的心智------dev 不查类型,以 npm run type-check 为准修复
  5. 装依赖用错包名 :脚手架命令是 npm create vue@latest,不是 npm create vite@latest 后手动拼 ts 模板(旧 vite vue-ts 模板已被官方边缘化)

九、今日小结

  • npm create vue@latest 问卷选 TS;新增 env.d.ts、tsconfig 三件套
  • dev/preview 不查类型,vue-tsc(type-check/build)才是关卡
  • tsconfig 记三条:strict 别关、paths 配别名、moduleResolution 保持 bundler
  • @ 别名 Vite 侧 + TS 侧双配置;.vue 的类型识别靠 Vue - Official 插件 + vue-tsc

下篇预告

interface、Ref<T>、泛型标注......TS 在响应式数据上的全部写法:ref 怎么标类型?reactive 和 interface 怎么配?返回值类型怎么声明?下一篇 041 ref 与 reactive 的 TS 类型标注。

相关推荐
水云桐程序员2 小时前
量子力学概论,量子力学概念总结
笔记·科技·学习·量子计算
前端·柱子2 小时前
q-floodfill白边锯齿?一招搞定抗锯齿边缘问题
前端·html·canva可画
darin_ฅ( ̳• ◡ • ̳)ฅ13 小时前
【 Obsidian】2026版-Obsidian安装Automatic Table of Contents 插件一键生成文章目录
笔记
2401_850122043 小时前
航空、轨交、汽车线束防护有什么不同?三大行业的共性、差异与选型逻辑
经验分享·笔记·科技
志尊宝3 小时前
Vue3 零基础每日笔记(037):动手封装 useMouse 与 useWindowSize——事件监听的标准模板
前端·javascript·vue.js·笔记·html5
有范先生3 小时前
【无标题】
笔记
hanlin034 小时前
刷题笔记:力扣第144题-二叉树的前序遍历
笔记·算法·leetcode
彧azz4 小时前
图的最短路径:Dijkstra与Floyd算法
数据结构·笔记·学习
人效思维笔记4 小时前
阿米巴推行前,经营者要先做好哪些准备?
经验分享·笔记·阿米巴·阿米巴经营·中国式阿米巴