从 tsup 到 tsdown
前言
最近,VoidZero 推出了一个 基于 rolldown 的全新的构建工具 tsdown。 本着尝鲜的态度,我把我在开发维护中的一部分开源项目,将构建工具从 tsup 切换到 tsdown。
迁移过程
自动迁移
tsdown
提供了迁移脚本,可以直接运行以下命令完成迁移:
npx tsdown migrate
pnpm dlx tsdown migrate
yarn dlx tsdown migrate
手动迁移
卸载 tsup,安装 tsdown
npmnpm uninstall -D tsup npm install -D tsdown
pnpmpnpm remove -D tsup pnpm add -D tsdown
yarnyarn remove -D tsup yarn add -D tsdown
重命名
tsup.config.{js,ts}
为tsdown.config.{js.ts}
修改
tsdown.config.{js,ts}
文件,将tsup
的配置替换为tsdown
的配置import { defineConfig } from 'tsdown' import { defineConfig } from 'tsup' export default defineConfig({ entry: 'src/index.ts', shims: true, dts: true, format: ['esm', 'cjs'], })
修改
package.json
中的scripts
字段{ "scripts": { // "build": "tsup", "build": "tsdown" } }
完成
迁移过程很简单,tsdown
几乎完全兼容 tsup
的所有配置项。
完成以上步骤后就可以直接运行 build
命令检查构建结果了。
收益
以 pengzhanbo/vuepress-theme-plume 为例, 在迁移前,使用 tsup
进行构建的时间开销大约在 7s 左右,而使用 tsdown
进行构建,时间开销缩短到了 0.3s !!! 这收益无疑是巨大的!
为什么快这么多?
事实上锅并不在于 tsup,而是在于 typescript
的 slow types
的存在。最主要的时间开销是在构建 dts
时。 由于 slow types
的存在,typescript
需要进行大量的类型推断才能确定导出的类型,这导致了构建 dts
的时间开销大大增加。
实际上我在做这次迁移时,我在 tsconfig.json
中新增了一项配置:isolatedDeclarations: true
,这项配置要求我们 对于代码中的每一个 export
,都需要进行显式的类型声明:
export const foo = 1 // ❌ Bad
export const foo: number = 1 // ✅ Good
export function foo(a: number, b: number) { // ❌ Bad
return a + b
}
export function foo(a: number, b: number): number { // ✅ Good
return a + b
}
当每一个 export
都有明确的类型声明时,typescript
就可以在构建 dts
时快速的完成类型推断,从而大大缩短了构建 dts
的时间开销。
同时,tsdown
使用 oxc-transform
生成 d.ts
文件,它比 typescript
编译器要更快一些。
二者的结合,使得构建时间极大的缩短了。
为什么选择 tsdown ?
从目前 tsdown
的更新进度而言,说实话我选择它的原因主要是 秉着尝鲜的态度。
tsdown
基于 rolldown
实现,而 rolldown
是下一代 vite
的底层构建工具,它使用 rust
编写, 得益于 vite
团队的优秀实践,全新的构建工具 rolldown
的性能表现非常出色,它比 esbuild
和 swc
要更快, 更小的内存开销。