Dts-Bundle-Generator
一个零配置的 TypeScript 声明文件(.d.ts)打包工具,支持类型树摇(tree-shaking),将多个模块的声明合并为单个 .d.ts 文件。
dts-bundle-generator 是 TypeScript 声明文件专用打包工具,直接在内存中编译并追踪依赖图,输出经过树摇的单一 .d.ts 文件,零配置即可生成干净的类型入口。
Dts-Bundle-Generator
一个零配置的 TypeScript 声明文件(
.d.ts)打包工具,支持类型树摇(tree-shaking),将多个模块的声明合并为单个.d.ts文件。
技术简介说明
在 TypeScript 库开发中,tsc --declaration 默认会为每个源文件生成独立的 .d.ts 文件,导致消费者需要依赖模块路径逐层引用,package.json 的 types 字段也无法指向一个干净的入口。dts-bundle-generator 正是为解决这一问题而诞生的——它直接从 TypeScript 源文件出发,在内存中编译并追踪依赖图,最终输出一个扁平化的、经过树摇的 .d.ts 文件。
与需要先编译再合并的两阶段方案不同,dts-bundle-generator 不产生任何中间文件,直接在内存中完成编译、依赖解析、类型内联和树摇,最终将结果写入单一输出文件。这种方式使得配置简单、集成成本低,且输出结果仅包含从入口文件可达的类型声明,有效减小了声明文件体积。
作为独立 CLI 工具,dts-bundle-generator 不绑定任何打包器生态(如 Rollup、Webpack),可以单独使用,也可以通过社区插件(rollup-plugin-dts-bundle-generator、vite-plugin-dts-bundle-generator、unplugin-dts-bundle-generator)集成到各类构建流程中。自 2017 年首次发布以来,累计发布 77 个版本,GitHub 获得约 870 星,是 TypeScript 声明打包领域最成熟、使用最广泛的专用工具之一。
基本信息
| 字段 | 内容 |
|---|---|
| 官网 | https://www.npmjs.com/package/dts-bundle-generator |
| GitHub | https://github.com/timocov/dts-bundle-generator |
| License | MIT |
| 最新版本 | v9.5.1(2024 年 4 月 21 日发布) |
| 主要维护者 | timocov(个人维护) |
| GitHub Stars | ~868+ |
| 总发布次数 | 77 个版本 |
| 源码语言 | TypeScript(90.2%)、JavaScript(9.8%) |
| 运行时要求 | Node.js 12+ |
| npm 周下载量 | 约 50K–100K(含间接依赖) |
快速上手
安装
作为开发依赖安装(推荐):
# npm
npm install --save-dev dts-bundle-generator
# pnpm
pnpm add -D dts-bundle-generator
# yarn
yarn add -d dts-bundle-generator全局安装:
npm install -g dts-bundle-generator前置要求:
- 项目的
tsconfig.json中必须启用"declaration": true编译选项 - TypeScript 版本 3.x 及以上均可正常工作
基础配置
最简 CLI 使用:
# 生成打包后的声明文件
dts-bundle-generator -o dist/index.d.ts src/index.ts使用配置文件(推荐用于复杂项目):
在项目根目录创建 dts-bundle-generator.config.json:
{
"compilationOptions": {
"preferredConfigPath": "./tsconfig.json"
},
"entries": [
{
"filePath": "./src/index.ts",
"outFile": "./dist/index.d.ts",
"libraries": {
"inlinedLibraries": []
},
"output": {
"sortNodes": true,
"noBanner": false
}
}
]
}然后运行:
dts-bundle-generator --config ./dts-bundle-generator.config.json也支持 JS 格式的配置文件(CommonJS 导出),可使用 @ts-check 进行类型校验:
// @ts-check
/** @type {import('dts-bundle-generator/config-schema').BundlerConfig} */
const config = {
compilationOptions: {
preferredConfigPath: './tsconfig.json',
},
entries: [
{
filePath: './src/index.ts',
outFile: './dist/index.d.ts',
output: {
sortNodes: true,
},
},
],
};
module.exports = config;最小示例
项目结构:
my-lib/
├── src/
│ ├── index.ts # 入口文件
│ └── types.ts # 类型定义
├── tsconfig.json
└── package.json
src/types.ts:
export interface User {
id: number;
name: string;
email: string;
}
export type Role = 'admin' | 'user' | 'guest';
// 未从入口导出的类型会被树摇移除
export interface InternalLog {
timestamp: Date;
level: string;
}src/index.ts:
export type { User, Role } from './types';
export function createUser(name: string, email: string): User {
return { id: Date.now(), name, email };
}执行打包:
dts-bundle-generator -o dist/index.d.ts src/index.ts生成的 dist/index.d.ts:
// 仅包含从入口可达的 User 和 Role,InternalLog 被树摇移除
export interface User {
id: number;
name: string;
email: string;
}
export type Role = 'admin' | 'user' | 'guest';
export declare function createUser(name: string, email: string): User;核心概念与架构
工作原理
dts-bundle-generator 的核心流程分为四个阶段:
-
内存编译:直接使用 TypeScript Compiler API 读取源文件,在内存中完成类型检查与声明生成,不向磁盘写入任何中间
.d.ts文件。 -
依赖图追踪:从指定的入口文件出发,递归解析所有
import/export引用,构建完整的依赖图。工具会自动区分本地文件、node_modules依赖和@types包。 -
类型内联与树摇:将依赖图中可达的声明内联到输出文件中,同时移除所有从入口不可达的类型(树摇)。对于第三方依赖,支持三种策略:内联(inline)、外部导入(import)和三斜线引用(triple-slash reference)。
-
输出生成:将所有内联的声明合并、排序(可选),输出为单个扁平化的
.d.ts文件。
核心概念
- Entry(入口):打包的起始文件,所有类型追踪从此开始。支持多入口,每个入口生成独立的输出文件。
- Inline(内联):将第三方库的类型声明直接嵌入输出文件,而非通过
import引用。 - External(外部):保留对第三方库的
import语句,不内联其类型。 - Tree-shaking(树摇):移除所有从入口文件不可达的类型声明,确保输出文件最小化。
- UMD Namespace:可选地为输出添加
export as namespace声明,支持 UMD 模块格式。
核心特性
-
零配置启动:只需提供入口文件和输出路径即可运行,无需复杂的配置文件。项目默认行为覆盖了绝大多数使用场景。
-
类型树摇(Tree-shaking):自动移除从入口不可达的类型声明,输出文件体积最小化。对于包含大量内部类型的库尤为有用。
-
内存编译,无中间文件:直接在内存中完成 TypeScript 编译,不产生临时
.d.ts文件,避免磁盘 I/O 和临时目录清理问题。 -
多入口支持:支持在单次运行中处理多个入口文件,每个入口生成独立的输出文件,适合具有多个导出路径的库。
-
灵活的第三方依赖控制:对每个第三方库可分别指定内联(inline)、外部导入(import)或三斜线引用策略,精确控制输出内容。
-
UMD 命名空间支持:通过
--umd-module-name参数生成export as namespace声明,兼容 UMD 模块格式。 -
配置文件支持:支持 JSON 和 JS 两种格式的配置文件,JS 配置文件可使用
@ts-check进行类型校验,获得完整的 IDE 智能提示。 -
declare global内联:可选地将全局声明(declare global)内联到输出中,适用于声明全局扩展(如Array.prototype扩展)的库。 -
const enum 处理:通过
respectPreserveConstEnum选项正确处理const enum,避免 TypeScript 编译器已知的问题(TypeScript#37774)。 -
验证与安全检查:默认对生成的
.d.ts进行验证(可通过--no-check跳过),支持--fail-on-class在输出包含类声明时报错(适用于纯函数式库)。
生态图
关键依赖
| 依赖 | 用途 |
|---|---|
typescript | 核心编译器,使用 TypeScript Compiler API 进行声明生成 |
yargs | CLI 参数解析 |
dts-bundle-generator 依赖极少(仅 2 个运行时依赖),这是其轻量化的重要原因。
社区集成插件
| 插件 | 说明 | 最新版本 |
|---|---|---|
| rollup-plugin-dts-bundle-generator | 将 dts-bundle-generator 封装为 Rollup 插件 | — |
| vite-plugin-dts-bundle-generator | Vite 插件封装,v2.1.2 | v2.1.2 |
| unplugin-dts-bundle-generator | 通用 unplugin 封装,支持 Vite / Rollup / Webpack / esbuild 等多打包器 | — |
相关工具生态
dts-bundle-generator 常与以下构建工具配合使用:
- tsup:基于 esbuild 的零配置 TS 库打包工具,声明打包可选用 dts-bundle-generator 或 rollup-plugin-dts
- unbuild:UnJS 生态的统一构建工具,底层可选 dts-bundle-generator 或 rollup-plugin-dts 作为声明引擎
- ts-lib-utils:专注于工具库的构建方案
社区规模
- GitHub Stars:~868+
- npm 周下载量:约 50K–100K(含作为间接依赖的下载)
- 累计发布 77 个版本,总提交 605+
- 开放 Issue:约 28 个
适用场景
-
TypeScript 工具库打包:最常见的场景。将库的多个内部模块的声明合并为单个入口
.d.ts文件,使消费者通过import { xxx } from 'your-lib'即可获得完整类型支持。 -
npm 包发布前类型准备:在
npm publish前运行,确保发布的包包含一个干净、扁平的类型入口,避免消费者遇到类型路径解析问题。 -
Monorepo 内部包的类型导出:在 pnpm workspace 或 Turborepo 等 monorepo 中,为内部包生成统一类型文件,简化包间类型依赖。
-
UMD 库的全局类型声明:通过
--umd-module-name生成带export as namespace的声明,同时支持 ESM / CJS / UMD 消费方式。 -
多入口库的类型打包:对于有多个导出路径(如
lib/core、lib/utils)的库,利用多入口配置一次生成所有声明文件。 -
CI/CD 中的类型验证:利用
--fail-on-class等选项在 CI 中强制保证输出符合规范(如纯函数式库不允许暴露类声明)。 -
库文档生成辅助:扁平化的
.d.ts文件更易于 API 文档工具(如 TypeDoc)解析,可作为文档生成流程的前置步骤。
开发与工程化
典型构建流程
// package.json
{
"scripts": {
"build:js": "tsc",
"build:dts": "dts-bundle-generator -o dist/index.d.ts src/index.ts",
"build": "pnpm build:js && pnpm build:dts",
"prepublishOnly": "pnpm build"
}
}与 CI/CD 集成
GitHub Actions 示例:
name: Build & Publish
on:
push:
tags: ['v*']
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
registry-url: 'https://registry.npmjs.org'
- run: npm install -g pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm build:dts
- run: pnpm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}工程化最佳实践
-
将声明打包作为独立步骤:在
package.json中单独定义build:dts脚本,与 JS 编译步骤解耦,便于独立调试。 -
使用配置文件管理复杂配置:对于多入口、多依赖策略的项目,使用
dts-bundle-generator.config.json或.js统一管理。 -
将生成的
.d.ts纳入.gitignore:声明文件作为构建产物,不应提交到版本库。 -
在
prepublishOnly中运行:确保发布前总是生成最新的声明文件,避免发布过期的类型。 -
Monorepo 中注意符号链接:pnpm workspace 默认使用符号链接,可尝试
--follow-symlinks=false解决路径解析问题。
性能与安全
性能特点
- 内存编译:不写入中间文件,对于中小型库(<100 个源文件),打包通常在 1–3 秒内完成。
- v9.4.0 性能优化:2024 年 4 月发布的 v9.4.0 带来了显著的性能改进,优化了外部模块声明的处理和导入管理。
- TypeScript 编译时间占主导:打包性能主要受 TypeScript 编译器本身的类型检查速度影响,工具自身的开销较小。
优化建议
- 合理设置外部依赖:将不需要内联的大型
@types包(如@types/react)设为外部导入,避免不必要的类型内联增加处理时间和输出体积。 - 使用
noCheck跳过验证:在开发阶段或 CI 中快速迭代时,可使用--no-check跳过输出验证以加速构建。 - 避免过大的内联范围:谨慎配置
inlinedLibraries,避免将大量第三方类型全部内联。
安全注意事项
- 输入文件信任:dts-bundle-generator 读取并编译指定的 TypeScript 源文件,确保源文件不受恶意代码注入。
- 配置文件执行:JS 格式的配置文件会被
require()执行,需确保配置文件来源可信。 - 依赖安全:定期审计
node_modules中第三方库的类型声明,避免恶意类型注入影响输出。
已知性能瓶颈
- 大型 monorepo:在包含数百个包的 monorepo 中,TypeScript 项目引用解析可能较慢(参见 Issue #269)。
- 深层
@types依赖:引入大量@types/*包时,全局类型解析和冲突检测可能影响性能。 - 复杂的条件类型和泛型:极端复杂的类型运算会增加 TypeScript 编译器的处理时间。
技术对比
与同类工具对比
| 维度 | dts-bundle-generator | rollup-plugin-dts | api-extractor | unbuild (dts) | dtsbuild |
|---|---|---|---|---|---|
| 类型 | 独立 CLI 工具 | Rollup 插件 | 独立 CLI 工具 | 构建工具(封装上述工具) | 独立 CLI 工具 |
| 输入 | 原始 .ts 文件 | 预编译的 .d.ts 文件 | 预编译的 .d.ts 文件 | 原始 .ts 文件 | 原始 .ts 文件 |
| 编译方式 | 内存编译,无中间文件 | 需先运行 tsc 生成 .d.ts | 需先运行 tsc 生成 .d.ts | 自动处理 | 内存编译 |
| 类型树摇 | ✅ 支持 | ✅ 通过 Rollup 支持 | ❌ 不支持 | ✅ 依赖底层引擎 | ✅ 支持 |
| 配置复杂度 | 低(零配置可用) | 中(需 Rollup 配置) | 高(配置文件复杂) | 低 | 低 |
| 多入口 | ✅ 原生支持 | ⚠️ 需配置多个入口 | ❌ 传统上单入口 | ✅ | ✅ |
| 打包器集成 | 需通过社区插件 | 原生 Rollup 插件 | 无 | 内置 | 无 |
| TSDoc 支持 | 基础 | 基础 JSDoc | 完整 TSDoc 标签处理 | 依赖底层引擎 | 基础 |
| 维护状态 | 最近更新 2024-04 | 活跃(有分支版本) | 活跃(Microsoft) | 活跃(UnJS) | 较新 |
| GitHub Stars | ~868 | ~873 | ~6K+ | ~4K+ | 较新 |
选型建议
- 选 dts-bundle-generator:需要零配置、独立的声明打包方案,直接使用
.ts源文件,不需要与 Rollup 深度集成。 - 选 rollup-plugin-dts:已在使用 Rollup 构建 JS,希望声明打包与 JS 打包共享同一套插件管道。
- 选 api-extractor:需要严格的 API 管理(如 TSDoc 标签控制可见性)、API 报告生成、适合大型企业 monorepo。
- 选 unbuild:使用 UnJS / Nuxt 生态,希望一个工具解决 JS 打包 + 声明打包 +
package.json生成。 - 选 dtsbuild:追求更现代的 TypeScript-first 实现和更好的启发式算法,新项目可优先考虑。
最佳实践
生产环境建议
-
固定版本号:在
package.json中使用精确版本而非范围版本(如"9.5.1"而非"^9.5.1"),避免自动升级带来的输出格式变化。 -
启用输出验证:生产构建中保留默认的
.d.ts验证(不使用--no-check),确保生成的声明文件语法正确。 -
使用
noBanner保持输出干净:若不希望生成的文件中包含"Generated by dts-bundle-generator"注释,在配置中设置noBanner: true。 -
合理区分内联与外部依赖:
- 自有组织内的包(如
@my-company/utils)→ 内联 - 大型框架类型(如
react、vue)→ 外部导入 @types/*全局类型 → 根据实际需要选择
- 自有组织内的包(如
-
多入口配置示例(推荐模式):
{
"entries": [
{
"filePath": "./src/index.ts",
"outFile": "./dist/index.d.ts",
"output": { "sortNodes": true }
},
{
"filePath": "./src/core.ts",
"outFile": "./dist/core.d.ts",
"output": { "sortNodes": true }
}
]
}常见陷阱
- 忘记启用
declaration: true:tsconfig.json中未启用声明生成会导致编译失败。 - Monorepo 符号链接问题:pnpm workspace 中可能需要设置
followSymlinks: false或正确配置tsconfig的paths。 @types包冲突:引入多个@types/*包时可能出现全局命名冲突,使用allowedTypesLibraries白名单控制。- const enum 陷阱:直接使用
const enum可能导致消费者编译错误,使用respectPreserveConstEnum: true处理。 - 内部类型意外导出:默认情况下所有引用的接口/类型都会被标记为导出,使用
exportReferencedTypes: false仅导出源码中显式导出的类型。
推荐模式
# 推荐的完整 CLI 调用
dts-bundle-generator \
--config ./dts-bundle-generator.config.json \
--no-banner \
--sort-output-nodes技术局限与边界
已知限制
- 不支持 JavaScript 源文件:必须从
.ts/.tsx文件出发,无法直接处理纯 JavaScript 项目的类型生成。 - 不支持预处理器:不处理 Sass/Less 等非 TypeScript 预处理器生成的文件,仅关注类型声明。
- 类声明处理有限:对于包含大量复杂类继承体系的库,生成的声明可能包含不必要的类定义(可使用
--fail-on-class检测)。 - 全局模块声明处理:
declare module 'external-module'形式的声明默认不内联,需手动启用inlineDeclareExternals。 - 声明合并(Declaration Merging)场景:对于使用 TypeScript 声明合并(如全局扩展接口)的库,行为可能不符合预期。
不适用场景
- 需要完整 API 报告生成:如果需要 API 变更检测、TSDoc 标签驱动可见性控制,应选用 api-extractor。
- 需要与 Rollup 深度集成:如果项目已使用 Rollup 管道,rollup-plugin-dts 可能是更自然的选择。
- 纯 JavaScript 库:对于没有 TypeScript 源码的 JavaScript 库,需要先手动编写
.d.ts或使用其他工具生成。 - 需要类型代码分割:dts-bundle-generator 始终生成单一文件,不支持按 chunk 分割类型(可考虑
@sxzz/rolldown-plugin-dts)。
权衡取舍
- 简单性 vs 功能完整性:dts-bundle-generator 以零配置和简单性著称,但在高级功能(如 TSDoc 处理、API 报告)方面不如 api-extractor 完整。
- 独立性 vs 生态集成:作为独立 CLI,灵活性高但需要额外的插件才能融入 Rollup / Vite 生态。
- 内存编译 vs 可调试性:不产生中间文件使流程简洁,但在排查问题时缺少可视化的中间产物。
迁移注意事项
- 从
tsc --declaration迁移时,确保入口文件正确导出所有需要暴露的类型。 - 从 rollup-plugin-dts 迁移时,注意输入差异:dts-bundle-generator 接受
.ts源文件而非.d.ts。 - 从 api-extractor 迁移时,注意 TSDoc 标签驱动的可见性控制不可用,需要手动管理导出。
学习资源
官方文档
- GitHub 仓库 README — 核心文档,包含 CLI 参数说明和配置参考
- 配置文件格式文档 — 完整的配置文件 schema 说明
- npm 包页面 — 版本历史和安装说明
- API 文档(jsDocs.io) — 程序化 API 参考
教程与文章
- 推荐一款强大的 TypeScript 定义文件打包工具:DTS Bundle Generator(CSDN) — 中文入门教程
- Tool to generate a single bundle of d.ts(Reddit r/typescript) — 社区讨论与使用经验
- TypeScript library tips: Rollup your types!(Medium) — TypeScript 库打包最佳实践
社区资源
- GitHub Discussions — 官方讨论区,包含工具对比、功能请求和问答
- GitHub Issues — Bug 报告和功能讨论(~28 个开放 issue)
- 工具对比讨论 — 社区维护的同类工具对比帖
2026 年现状
版本状态
截至 2026 年 7 月,最新版本为 v9.5.1(2024 年 4 月 21 日发布),距上次发布已超过 2 年。虽然近期无新版本发布,但社区仍持续报告 issue(最近的 issue 出现在 2025 年 8 月),说明该工具仍在被广泛使用。
近期版本更新回顾
| 版本 | 日期 | 要点 |
|---|---|---|
| v9.5.1 | 2024-04-21 | 修复命名空间导入在输出中消失的问题 |
| v9.5.0 | 2024-04-17 | 修复对象/数组绑定模式语法导致的构建崩溃 |
| v9.4.1 | 2024-04-17 | 修复递归类型中部分类型被错误移除的问题 |
| v9.4.0 | 2024-04-15 | 性能优化;修复外部模块声明和导入管理问题 |
| v9.3.1 | 2024-02-03 | 修复处理变量时日志输出过多警告的问题 |
发展趋势
- 稳定但非活跃维护:工具功能已趋于稳定,维护者以修复 bug 为主,新功能开发节奏放缓。
- 竞争工具涌现:
dtsbuild、@sxzz/rolldown-plugin-dts等新工具提供了更现代的 TypeScript-first 实现,Rolldown 生态的类型代码分割方案也在成熟中。 - 社区集成持续扩展:
unplugin-dts-bundle-generator等通用封装使其适配 Vite / Rollup / Webpack / esbuild 等多打包器环境。
社区活跃度
- GitHub:~868 Stars,28 个开放 Issue,Issue 和 Discussion 仍有新活动
- npm:稳定的下载量,被众多知名库作为开发依赖使用
- 维护模式:个人项目,维护者 timocov 以 bug 修复为主,无公开的未来路线图
未来展望
dts-bundle-generator 作为 TypeScript 声明打包领域的"老牌"工具,其核心价值——零配置、内存编译、类型树摇——仍然是同类工具中的标杆。虽然维护节奏放缓,但其稳定性和简洁性使其在中小型 TypeScript 库开发中仍是首选方案。
对于新项目,可关注 dtsbuild(更现代的启发式算法)和 Rolldown 生态的类型分割方案;对于已有项目,dts-bundle-generator 仍是经过大量生产验证的可靠选择。若项目需要更严格的 API 管理,建议评估 api-extractor 或切换到 unbuild 的统一构建方案。