首页
/ Nuxt 的 tsconfig.json 机制解析:四个自动生成配置文件与 nuxt.config.ts 定制指南

Nuxt 的 tsconfig.json 机制解析:四个自动生成配置文件与 nuxt.config.ts 定制指南

2026-09-04 12:20:19作者:宣海椒Queenly

Nuxt 不会让你手写一份大而全的 tsconfig.json,而是按运行上下文自动拆分生成 tsconfig.app.jsontsconfig.server.jsontsconfig.node.jsontsconfig.shared.json 四个文件,项目根目录只需放置一个基于 references 的“壳”配置。本文基于仓库中 tsconfig 文档 展开,结合 类型生成源码Nitro 服务端集成代码,讲清楚这四个文件各自覆盖哪些代码、默认的 compilerOptions 是什么、以及如何在 nuxt.config.ts 中正确地扩展它们而不破坏 Nuxt 或模块依赖的内部约定。

项目根目录:一个只含 references 的 tsconfig.json

Nuxt 会在 .nuxt 目录下自动生成多份 TypeScript 配置(.nuxt/tsconfig.app.json.nuxt/tsconfig.server.json.nuxt/tsconfig.node.json.nuxt/tsconfig.shared.json),每份都包含 Nuxt 推荐的基线 compilerOptions,并进一步写入 自动导入 的类型引用、类型化 API 路由 的声明、路径别名(paths)等内容。

因此,你的 Nuxt 项目根目录应当只放置这样一个文件:

{
  "files": [],
  "references": [
    { "path": "./.nuxt/tsconfig.app.json" },
    { "path": "./.nuxt/tsconfig.server.json" },
    { "path": "./.nuxt/tsconfig.shared.json" },
    { "path": "./.nuxt/tsconfig.node.json" }
  ]
}

注意:不推荐直接修改根目录这个文件的 contents,因为这样做可能覆盖 Nuxt 或其他模块依赖的重要设置。正确的做法是通过 nuxt.config.ts 扩展生成结果(见下文“通过 nuxt.config.ts 定制”一节)。

这种“根配置只做 references 分发”的设计是 TypeScript Project References 的典型用法:每个上下文拥有独立的 compilerOptionsinclude 边界,编辑器可以按文件所属上下文应用正确规则。更多类型上下文背景见 TypeScript 概念文档 的 project references 部分。

从源码看,根目录文件本身不含任何编译规则("files": [] 表示它不直接编译文件),真正干活的是四个引用目标。Nuxt 在构建流程中明确维护了一份“受管理文件”清单,builder.ts 中写有:

const generatedTsConfigs = ['tsconfig.json', 'tsconfig.app.json', 'tsconfig.server.json', 'tsconfig.node.json', 'tsconfig.shared.json']

这说明这些文件(包括 .nuxt/tsconfig.json 这个兼容旧版的 legacy 文件)全部由框架托管,手动改动会在下次类型重新生成时被覆盖。

四个 tsconfig 文件分别覆盖什么

各上下文的职责可以从生成逻辑直接确认。packages/kit/src/template.ts 中的 writeTypes 负责写出 app/node/shared 三份配置(template.ts#L664-L688):

const appTsConfigPath = resolve(typesDir, 'tsconfig.app.json')
const legacyTsConfigPath = resolve(typesDir, 'tsconfig.json')
const nodeTsConfigPath = resolve(typesDir, 'tsconfig.node.json')
const sharedTsConfigPath = resolve(typesDir, 'tsconfig.shared.json')

tsconfig.server.json 由 Nitro 层写出:nitro-server/src/index.tstsconfigPath 指向 join(typesDir, 'tsconfig.server.json'),并把 server 目录、shared 声明等纳入扫描范围。

生成的文件 覆盖的代码上下文 主要 include 内容(源码推导)
tsconfig.app.json Vue 应用代码(客户端 + SSR 组件) app/、层目录中的 app/**、模块 runtime,以及 .nuxt/nuxt.d.ts
tsconfig.server.json Nitro 服务端(server/ 目录、API 路由) 由 Nitro 集成写入,含 server/**types/nitro
tsconfig.node.json 加载 nuxt.config.ts 与模块的环境(Node) nuxt.config.*modules/*.*.nuxt/nuxt.node.d.ts
tsconfig.shared.json shared/ 目录(客户端与服务端共享代码) shared/**、模块 shared/**.nuxt/nuxt.shared.d.ts

include 的具体模式由 resolveLayerPaths 统一计算,例如 node 上下文固定包含 nuxt.config.*layers/*/nuxt.config.*layers/*/modules/*.*shared 上下文固定包含各层的 shared/**。这样即使使用了 layers,每个上下文的类型边界也不会互相污染。

值得注意的是写入策略:writeTypes 内部使用 writeIfChanged 只有内容变化才落盘(template.ts#L695-L699),源码注释解释了原因——类型文件每次启动都会重新生成且通常完全一致,保持 mtime 不变可以让编辑器和 tsc --watch 跳过重复工作。

默认 compilerOptions:Nuxt 替你做了哪些决定

_generateTypes 中通过 defu 合并出了一份基线配置(template.ts#L409-L465),核心默认值包括:

  • 严格度strict(可通过 typescript.strict 关闭,默认 true)、noUncheckedIndexedAccessnoImplicitOverrideforceConsistentCasingInFileNamesfuture.compatibilityVersion >= 5 时还会追加 noUncheckedSideEffectImports
  • 模块系统module: 'preserve'(检测到 TypeScript >= 5.4 时,否则回退 ESNext)、verbatimModuleSyntaxisolatedModulesmoduleDetection: 'force'esModuleInteropresolveJsonModule
  • 不产出产物noEmit: true——类型检查交给编辑器或 vue-tsc,构建由 Vite/Webpack/Rspack 完成。
  • 关闭环境类型自动扫描types: [],所有第三方/模块类型必须通过显式 references 引入(写入 nuxt.d.ts / nuxt.node.d.ts / nuxt.shared.d.ts 声明文件),避免 Node、DOM 等全局类型在错误的上下文里泄漏。
  • 路径别名paths 初始为空对象,随后由 Nuxt 遍历 nuxt.options.alias 填充,把 ~@#build、layer 别名等全部转成相对 .nuxt 目录的路径,并按固定顺序排序(sortTsPathstypescript.hoist 的包路径置顶,layer 别名居中,#build 置底)。

文档中提到的两类“例外”,在源码里有一一对应:

  1. DOM/Vue 专属选项只作用于 app。源码中明确列出了应用专属选项清单(template.ts#L473-L480):
const appOnlyCompilerOptions = ['lib', 'libReplacement', 'jsx', 'jsxImportSource', 'noUncheckedSideEffectImports', 'experimentalDecorators'] as const
const nonAppCompilerOptions = (): NonNullable<TSConfig['compilerOptions']> => {
  const compilerOptions = { ...baseTsConfig.compilerOptions }
  for (const key of appOnlyCompilerOptions) {
    delete compilerOptions[key]
  }
  return { ...compilerOptions, noEmit: true, types: [], paths: {} }
}

也就是说,即使你在 typescript.tsConfig 里设置了 libjsxjsxImportSourcenode/shared/server 上下文也会在生成时被剥离掉这些选项。

  1. typespathsnoEmit 由 Nuxt 按上下文管理nonAppCompilerOptions() 强制 noEmit: truetypes: []paths: {}(随后由别名填充逻辑重写),所以在全局 tsConfig 里设置这三项对非 app 上下文无效——必须用对应的按上下文选项覆盖。

通过 nuxt.config.ts 定制 TypeScript 配置

所有定制入口都在 nuxt.config.tstypescript 块中:typescript.tsConfig所有上下文设置共享的 compilerOptions,而 appTsConfigsharedTsConfignodeTsConfigserverTsConfig 分别针对单个上下文覆盖。

export default defineNuxtConfig({
  typescript: {
    // shared compiler options for every generated tsconfig
    tsConfig: {
      compilerOptions: {
        // ...
      },
    },
    // customize tsconfig.app.json
    appTsConfig: {
      // ...
    },
    // customize tsconfig.shared.json
    sharedTsConfig: {
      // ...
    },
    // customize tsconfig.node.json
    nodeTsConfig: {
      // ...
    },
    // customize tsconfig.server.json
    serverTsConfig: {
      // ...
    },
  },
})

合并优先级可以直接从 defu 调用顺序读出(template.ts#L409-L499):

const baseTsConfig: TSConfig = defu(nuxt.options.typescript?.tsConfig, { /* Nuxt 默认值 */ })
const tsConfig: TSConfig = defu(nuxt.options.typescript?.appTsConfig, baseTsConfig)      // app 上下文
const nodeTsConfig: TSConfig = defu(nuxt.options.typescript?.nodeTsConfig, { ... })       // node 上下文
const sharedTsConfig: TSConfig = defu(nuxt.options.typescript?.sharedTsConfig, { ... })   // shared 上下文

即:按上下文的选项(appTsConfig 等) > 全局 tsConfig > Nuxt 内置默认值。schema 中的注释(schema.ts#L1953-L1982)同样说明:tsConfigcompilerOptions 对所有生成的 tsconfig 生效,而 includeexcludevueCompilerOptions 只作用于 tsconfig.app.json(及 legacy 的 .nuxt/tsconfig.json)。

另外两个与文档一致的行为值得注意:

  • server 上下文有双入口typescript.serverTsConfignitro.typescript.tsConfig 都会扩展 tsconfig.server.json 并保持同步,设置任意一个效果相同。官方建议优先使用 typescript.serverTsConfig,把四个上下文的定制集中在一个位置。
  • 其他可用的 typescript 选项(默认值见 config/typescript.ts):strict(默认 true)、typeCheck(默认 false,设为 true'build' 可启用类型检查,需安装 typescriptvue-tsc)、hoist(为 pnpm 等严格安装场景生成深路径别名,默认包含 vuenuxt 等核心依赖)、shim(是否生成 .vue 声明文件,默认 false)、includeWorkspace(把父 workspace 纳入类型范围,模块/主题作者常用,默认 false)。

类型引用:nuxt.d.ts 与模块类型如何进入上下文

四个 tsconfig 的 include 起点各不相同(./nuxt.d.ts./nuxt.node.d.ts./nuxt.shared.d.ts),这些声明文件由同一次生成流程写入,内容是 Nuxt 收集到的 TSReference/// <reference types="..." />)与自定义声明。模块安装时,Nuxt 会把每个模块包注册为类型引用(template.ts#L557-L572),分别加入 app 上下文与 node 上下文的声明文件——这就是为什么安装一个模块后无需手动 import 就能在模板和配置里用它的类型。

prepare:types 钩子(template.ts#L576)则允许模块在写盘前向这些引用和声明追加内容,Nitro 正是通过同类机制在写 .nuxt/tsconfig.server.json 前注入自定义 references 与声明(augments.ts#L86)。

验证与参考

总结一句话:把根 tsconfig.json 当作只读分发器,所有 TypeScript 定制都走 nuxt.config.tstypescript 块;记住 DOM/Vue 选项只进 app、types/paths/noEmit 按上下文管理、server 定制优先用 serverTsConfig,就能在享受 Nuxt 生成的完整类型体系的同时保持可控的覆盖能力。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.79 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
988
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384