Vben精讲:21-详解web-antd:tsconfig.json

文章目录

为什么需要三个配置文件?

apps\web-antd\tsconfig.json

apps\web-antd\tsconfig.node.json

apps\web-antd\vite.config.ts

核心概念图

复制代码
┌─────────────────────────────────────────────────────┐
│                    项目根目录                        │
├─────────────────────────────────────────────────────┤
│                                                     │
│  ┌─────────────────┐    ┌──────────────────────┐   │
│  │   tsconfig.json │    │  tsconfig.node.json  │   │
│  │   (浏览器端)     │◄───│    (Node.js端)       │   │
│  │                 │    │                      │   │
│  │  包含: src/**/*  │    │  包含: vite.config.ts│   │
│  └────────┬────────┘    └──────────┬───────────┘   │
│           │                        │               │
│           │    依赖关系             │               │
│           └────────────┬───────────┘               │
│                        │                           │
│                 ┌──────▼──────┐                    │
│                 │vite.config.ts│                    │
│                 │  (桥梁文件)   │                    │
│                 └──────────────┘                    │
└─────────────────────────────────────────────────────┘

tsconfig.json - 浏览器端的"宪法"

作用

比喻 :如果把项目比作一个国家,tsconfig.json 就是宪法------它定义了所有浏览器端代码的基本规则。

示例

apps\web-antd\tsconfig.json

json 复制代码
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "@vben/tsconfig/web-app.json",  // 继承基础配置
  "compilerOptions": {
    "paths": {
      "#/*": ["./src/*"]      // 路径别名:#/ → src/
    }
  },
  "references": [{ "path": "./tsconfig.node.json" }],  // 依赖 Node 配置
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}

apps\web-antd\src\app.vue

typescript 复制代码
import { antdLocale } from '#/locales';

关键配置项详解

配置项 含义 为什么这样设置?
extends 继承基础配置 避免重复编写通用配置(如 strict: true
paths 路径别名 #/utils 映射到 src/utils,让导入更简洁
references 项目引用 告诉 TypeScript:"我需要 tsconfig.node.json 的类型"
include 包含文件 只处理 src/ 下的代码,不包含配置文件

tsconfig.node.json - Node.js 的"专业宪法"

为什么需要独立的 Node 配置?

比喻:就像一个公司有"国内市场部"和"国际市场部",虽然都是公司的一部分,但工作方式、工具、规则完全不同。

真实项目示例

json 复制代码
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "@vben/tsconfig/node.json",  // 继承 Node 基础配置
  "compilerOptions": {
    "composite": true,                    // 启用项目引用
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
    "noEmit": false                       // 需要生成类型文件
  },
  "include": ["vite.config.ts"]           // 只包含配置文件
}

关键配置项对比

配置项 tsconfig.json tsconfig.node.json 原因
lib ["DOM", "ESNext"] ["ESNext"] Node 环境没有 DOM
types ["vite/client"] ["node"] 需要 Node.js 类型
moduleResolution "bundler" "node" 不同的模块解析方式
composite 不需要 需要 作为被引用的项目

文件归属图

复制代码
项目文件归属:
┌────────────────────────────────────────┐
│  tsconfig.json 负责:                   │
│  ├── src/                              │
│  │   ├── App.vue                       │
│  │   ├── main.ts                       │
│  │   └── components/                   │
│  └── 所有浏览器端代码                   │
├────────────────────────────────────────┤
│  tsconfig.node.json 负责:              │
│  ├── vite.config.ts                    │
│  ├── vitest.config.ts (如果有)         │
│  └── 所有 Node.js 脚本                 │
└────────────────────────────────────────┘

vite.config.ts - 连接两端的"桥梁"

三重视角

比喻vite.config.ts 就像一个"翻译官":

  • 它用 Node.js 的语言(tsconfig.node.json)编写
  • 它定义浏览器端的规则(影响 tsconfig.json
  • 它连接两个世界

类型来源分析

typescript 复制代码
import { defineConfig } from 'vite'
//       ↑ 这个类型从哪里来?

// 1. tsconfig.node.json 中配置了 types: ["node"]
// 2. 所以能找到 @types/node 中的类型
// 3. vite 包自带类型定义
// 4. 浏览器端代码通过 references 共享这些类型

类型传递流程

复制代码
vite.config.ts (Node.js 环境)
    │
    │ 1. 使用 Node.js 类型编译
    ▼
生成 .d.ts 类型文件 (通过 composite: true)
    │
    │ 2. 被 tsconfig.json 引用 (references)
    ▼
src/ 中的代码可以使用 Vite 的类型
    │
    │ 3. 例如 import.meta.env 的类型
    ▼
浏览器应用获得完整的类型提示

三者的协作关系

完整协作图

复制代码
┌─────────────────────────────────────────────────────────────┐
│                   开发工作流程                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  开发者写代码                                               │
│      ↓                                                     │
│  编辑器中打开 .vue 文件                                    │
│      ↓                                                     │
│  VSCode 读取 tsconfig.json                                 │
│      ↓                                                     │
│  看到 references → 加载 tsconfig.node.json                 │
│      ↓                                                     │
│  读取 vite.config.ts 的类型信息                            │
│      ↓                                                     │
│  为 import.meta.env 提供类型提示                           │
│      ↓                                                     │
│  开发者获得完整的智能提示 ✅                                │
│                                                             │
└─────────────────────────────────────────────────────────────┘

依赖关系矩阵

文件 依赖 被依赖 作用
tsconfig.json tsconfig.node.json src/ 下的代码 定义浏览器编译规则
tsconfig.node.json @vben/tsconfig/node.json tsconfig.jsonvite.config.ts 定义 Node 编译规则
vite.config.ts tsconfig.node.json src/ 代码(通过类型传递) 配置构建工具

构建顺序

复制代码
执行 tsc --build 时:

第1步:构建 tsconfig.node.json
        ↓
    生成 .tsbuildinfo 缓存
        ↓
第2步:构建 tsconfig.json
        ↓
    使用前者的类型信息
        ↓
第3步:生成最终的类型文件

常见问题与解决方案

找不到模块 'vite'

错误现象

typescript 复制代码
// ❌ 在 src/ 中报错
import { defineConfig } from 'vite'  // 找不到模块

原因src/ 使用的是浏览器配置,不包含 Node.js 类型。

解决方案

json 复制代码
// tsconfig.json 中添加 references
{
  "references": [{ "path": "./tsconfig.node.json" }]
}

VSCode 不识别 import.meta.env

错误现象

typescript 复制代码
// ❌ 类型报错
const apiUrl = import.meta.env.VITE_API_URL
// Property 'VITE_API_URL' does not exist on type 'ImportMetaEnv'

原因 :缺少 vite/client 类型。

解决方案

json 复制代码
// tsconfig.json
{
  "compilerOptions": {
    "types": ["vite/client"]  // 添加 Vite 客户端类型
  }
}

构建时类型不匹配

错误现象

复制代码
error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'

原因:浏览器和 Node.js 对某些 API 的类型定义不同。

解决方案

  • 确保 tsconfig.jsontsconfig.node.json 使用不同的 lib
  • 使用 /// <reference types="..." /> 明确指定类型

实践总结

配置检查清单

markdown 复制代码
☐ tsconfig.json
  ☐ 设置正确的 lib (DOM, ESNext)
  ☐ 配置 paths 别名
  ☐ 添加 references 指向 node 配置
  ☐ include 只包含 src/ 目录

☐ tsconfig.node.json
  ☐ 设置 composite: true
  ☐ 配置 types: ["node"]
  ☐ include 包含 vite.config.ts
  ☐ 设置正确的 moduleResolution

☐ vite.config.ts
  ☐ 使用 defineConfig
  ☐ 导出配置对象
  ☐ 类型由 tsconfig.node.json 提供

常见问题汇总

问题 答案
可以只用一个 tsconfig.json 吗? 小项目可以,但大型项目需要分离
references 中的路径怎么写? 相对于当前文件的路径
composite: true 是必须的吗? 被引用的项目必须设置
如何调试配置问题? 使用 tsc --showConfig 查看最终配置
生产环境需要这些配置文件吗? 不需要,它们是开发时用的

实用命令

bash 复制代码
# 查看最终配置
pnpm tsc --showConfig

# 检查类型(不输出文件)
pnpm tsc --noEmit

# 构建所有项目
pnpm tsc --build

# 构建特定项目
pnpm tsc --build tsconfig.node.json

# 清除缓存
rm -rf node_modules/.tmp/*.tsbuildinfo

VSCode翻译插件

Comment Translate

tencent-cloud-translate

参考资料

相关推荐
wc881 小时前
微软EDGE浏览器功能学习
前端·学习·edge
Csvn2 小时前
🎯 原生 `<dialog>` 元素:终于可以扔掉一半的自定义弹窗组件了?
前端
Csvn2 小时前
🎨 CSS @layer:用「层叠优先级」终结样式打架的世纪难题
前端
濮水大叔2 小时前
不必把 Vue3 写成“麻花”:从状态碎片到对象协作,重新理解 Zova 的前端心智模型
前端·typescript·vue3·ioc·tsx·zova
Vuji3 小时前
MCP: 一条 tool 调用链路的旅程
前端·人工智能
万少4 小时前
DeepSeek-V4-Flash 正式版上线了,但这 3 个坑我帮你提前踩了
前端·javascript·后端
明月_清风4 小时前
🚀 Palantir Foundry 本体论实战:当 Ontology 从"知识图谱"进化为"企业操作系统"
前端·后端
驳是4 小时前
入坑 Nginx,看这一篇就够了
前端
宁风NF4 小时前
JavaScript:网络请求与前端通信
开发语言·前端·javascript·网络·学习·ecmascript