news 2026/9/10 16:26:52

tsdown root 选项详解:掌控输出目录结构映射,让入口路径与产物一一对应

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
tsdown root 选项详解:掌控输出目录结构映射,让入口路径与产物一一对应

tsdown root 选项详解:掌控输出目录结构映射,让入口路径与产物一一对应

【免费下载链接】airi💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-sama's altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi

tsdown 是 airi 这个大型 pnpm monorepo 中用于构建各 TypeScript 库的打包器,而root选项是决定「源码入口文件如何映射到输出路径」的关键开关。读完本文你将掌握root与 TypeScriptrootDir的关系、默认公共基目录的推导规则、CLI 与配置文件的完整用法,以及它在 unbundle(bundleless)模式下作为preserveModulesRoot影响产物结构的底层原理。

什么是 root:为输出结构映射指定根目录

root选项用于指定「输入文件根目录」,其作用是决定入口文件的路径如何映射为输出路径。可以把 tsdown 中的root类比为 TypeScripttsconfig.json里的rootDir概念:编译器/打包器需要知道「从哪个目录起算」来保留目录结构。

默认情况下,tsdown 会自动把**所有入口文件的公共基础目录(common base directory)**当作 root。显式设置root则允许你覆盖这一默认推导行为,从而精细控制输出目录层级。

在 tsdown 的完整能力地图中,root被归类在 Output Enhancement(输出增强)之下,官方定位描述为「root: 'src'— Control output directory mapping」,可参考 SKILL.md 中的 Build Options / Output Enhancement 索引表。

基本用法:CLI 与配置文件两种方式

root既可以在命令行直接传入,也可以在tsdown.config.ts配置文件中声明。

CLI 方式

tsdown --root src

配置文件方式

// tsdown.config.ts import { defineConfig } from 'tsdown' export default defineConfig({ entry: ['src/index.ts', 'src/utils/helper.ts'], root: 'src', })

配置文件通过defineConfig导出,root接受一个相对于执行 tsdown 所在目录(通常是包根目录)的路径字符串。

工作原理:默认公共基目录 vs 显式 root

默认行为:自动计算公共基目录

给定两个入口src/index.tssrc/utils/helper.ts,它们的公共基础目录是src/,因此默认产出如下结构,src前缀被剥除:

dist/ ├── index.js └── utils/ └── helper.js

显式设置 root: '.'

如果将 root 设为项目根目录.,则输出会保留src/前缀:

dist/ └── src/ ├── index.js └── utils/ └── helper.js

这两组结构的差异正是root的核心价值:决定目录前缀保留还是剥除。这与 TypeScript 的rootDir行为一致——输出目录结构永远以 root 为基准镜像映射。

与 outDir 的分工

需要区分两个容易混淆的选项:

选项作用对应文档
root决定入口路径到输出路径的映射基准(去掉/保留前缀)Root Directory
outDir决定产物写入到哪个目录(默认distOutput Directory

outDir是产物总目录,root决定outDir之下如何按源码目录结构摆放文件。例如root: '.'+ 默认outDir: 'dist',产出即上文dist/src/...结构。

root 具体影响的两件事

tsdown 中root主要作用于两个环节:

  1. 入口名称解析(Entry name resolution)当入口以数组形式给出(如['src/index.ts', 'src/utils/helper.ts'])时,各入口的输出文件名是相对root计算的。root 不同,同一份 entry 列表得到的相对路径(从而输出文件路径)就不同。

  2. Unbundle 模式(输出结构保持)当开启unbundle: true时,root会被当作preserveModulesRoot使用,直接控制「逐文件编译、镜像源码结构」模式下输出目录的挂载起点。可结合 Unbundle 模式说明 理解。

何时应该显式设置 root

满足以下任一需求时,应显式配置root

  • 自动推导出的公共基目录无法产生期望的输出结构;
  • 需要在输出路径中保留或剔除特定目录前缀(比如保留src/前缀,方便调试时在产物里定位对应源文件);
  • unbundle 模式下需要特定的目录映射(preserveModulesRoot语义)。

默认推导通常只适合入口相对集中、公共基目录恰好等于你想要去掉的那一层的情况。一旦入口跨度变大(比如既包含src/又包含scripts/下的文件),公共基目录可能变成项目根目录,此时就需要root显式介入。

常见模式:从配置示例到真实仓库用法

模式一:库保留 src/ 前缀 + unbundle

export default defineConfig({ entry: ['src/**/*.ts', '!**/*.test.ts'], root: '.', unbundle: true, })

该模式产出dist/src/...完整镜像,适合希望产物路径与源码路径几乎一致、便于用户按子路径 import 的库。

模式二:monorepo 包,去掉 src/ 前缀

export default defineConfig({ entry: ['src/index.ts'], root: 'src', unbundle: true, })

产出为dist/index.js等扁平或子目录结构,src/前缀被剥除。

airi 仓库中的实际印证

在 airi monorepo(见 pnpm-workspace.yaml)里,大量库包采用 tsdown 构建,且多配合unbundle: true使用,正属于root选项最有价值的应用场景。例如:

  • packages/audio/tsdown.config.ts:以对象形式声明多入口,并把audio-context/encoding/等子目录通过 entry key 映射到产物目录,同时开启unbundle: true
  • packages/i18n/tsdown.config.ts:通过entry对象 key(如locales/zh-Hans/index)显式规划输出子目录,配合unbundle: truecopy保持 i18n 资源结构;
  • packages/font-chillroundm/tsdown.config.ts、packages/font-departure-mono/tsdown.config.ts 等字体包同样使用unbundle: true模式构建。

从这些配置可以看出:airi 内部多数场景依赖「默认公共基目录 + entry key / 对象入口」即可得到理想结构;当需要改变前缀剥除策略或让 unbundle 的preserveModulesRoot落在特定目录时,才会引入显式root。这正是 Entry 选项文档 所强调的——对象入口 key 本身也是规划输出结构的一种手段。

模式三:纯 unbundle 场景参考

若同时希望产物可被按需深层导入,可参考完整 unbundle 组合(源自 Unbundle 模式说明):

export default defineConfig({ entry: ['src/**/*.ts', '!**/*.test.ts'], format: ['esm', 'cjs'], unbundle: true, dts: true, })

使用建议与注意事项

  1. 明确产物消费方式再定 root:若发布的是整体入口库(main/exports['.']指向单文件),通常无需显式root;若希望用户按my-lib/utils/helper深路径导入,则应保证 unbundle 产物结构可预期,必要时显式root
  2. 与 dts 保持一致:生成声明文件(dts: true)时,.d.ts的输出结构同样遵循入口映射规则,root 变更会影响.d.ts的目录摆放,需一并检查。
  3. 根目录即产物时要小心:不要让outDir落到项目根目录(尤其当 root 为.时),配合clean: true极易误删源码。详见 Output Directory 的警告。
  4. root 表达的是目录而非 glob:与entry支持 glob 与取反不同,root是一个具体目录;入口文件集合与排除规则应全部交给 entry 负责。

小结

root是 tsdown 输出路径体系中最容易被忽略、却对产物目录结构起决定性作用的选项:默认值来自所有入口的公共基目录,显式赋值则赋予开发者对「目录前缀保留与否」与「unbundle 模式下 preserveModulesRoot」的完全控制。在 airi 这样大量以 unbundle 方式发布多子模块库的 monorepo 中,理解rootentryunbundleoutDir的配合关系,是保证「产物目录与 package.json exports 子路径声明精确对应」的前提。

【免费下载链接】airi💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-sama's altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 16:25:01

CVAT 实战教程:从一条命令到 AI 自动标注的完整上手

CVAT 实战教程:从一条命令到 AI 自动标注的完整上手 【免费下载链接】cvat Computer Vision Annotation Tool (CVAT) is a leading platform for building high-quality visual datasets for vision AI. It offers open-source, cloud, and enterprise products, as…

作者头像 李华
网站建设 2026/9/10 16:16:31

安卓应用签名证书在线生成与安全实践指南

1. 安卓证书在线生成的核心价值与应用场景在安卓应用开发与分发过程中,数字证书扮演着至关重要的角色。传统本地生成证书的方式需要开发者手动配置Java Keytool环境,处理复杂的命令行参数,这对新手开发者尤其不友好。在线生成工具通过浏览器即…

作者头像 李华