tsdown 技能指南:在 airi 仓库中用好 Rolldown 驱动的 TypeScript 库打包器

原创2026-10-14 21:58:591,957 阅读
文章标签:AI 应用大模型AI Agent数字人前端后端桌面应用移动开发音频

tsdown 技能指南:在 airi 仓库中用好 Rolldown 驱动的 TypeScript 库打包器

本文面向在 airi 仓库中工作的 AI 编码代理(Claude Code 等)与开发者,系统介绍 .agents/skills/tsdown 这一 Agent Skill 的安装方式、知识范围与典型用法,并结合仓库内 packages/ 下大量真实 tsdown.config.ts 配置,说明如何用它把 TypeScript/JavaScript 库打包得又快又规范。读完本文,你将掌握 tsdown 的技能安装、配置项语义、CLI 用法与 tsup 迁移路径,并能在 monorepo 场景下落地多格式、多入口、声明文件与包校验的完整方案。

技能定位:tsdown 是什么,为什么需要 Agent Skill

tsdown 被官方定位为 "The Elegant Library Bundler"——一个面向 TypeScript/JavaScript 库作者的打包器,核心引擎是 Rust 编写的 Rolldown],配合 Oxc 工具链,为库开发提供开箱即用的完整方案。技能文档([.agents/skills/tsdown/SKILL.md)将其能力归纳为:

  • 简化配置:为库开发提供合理的默认值,样板代码极少;
  • 库专属特性:自动生成 TypeScript 声明、多格式输出、包发布前校验;
  • 面向未来:作为 Rolldown 官方项目,是 Rolldown Vite Library Mode 的基础。

tsdown 与底层 Rolldown 的关键差异(详见 .agents/skills/tsdown/references/guide-introduction.md)在于它包装了一层"库作者友好"能力:自动将 package.json 中的 dependencies、peerDependencies、optionalDependencies 外部化、DTS 生成、exports 字段生成、带键盘快捷键的 watch 模式、CSS 预处理流水线,以及基于 Node.js SEA(Single Executable Applications)的可执行文件打包。其设计受 Rollup、esbuild、tsup、unbuild 启发。

README.md 描述的正是把以上知识封装成 Agent Skill 的方式:安装之后,Claude Code 等编码代理在构建库、配置打包器、生成类型声明、多格式构建、从 tsup 迁移、构建框架组件库等场景下会自动调用这些知识,而不是靠模型凭记忆猜测 tsdown 的 API。

运行时要求(容易踩坑的点)

tsdown 自身运行需要 Node.js 22.18.0 或更高(仅构建期要求),同时提供对 Deno 和 Bun 的实验性支持。需要特别强调的是:打包产物不受此限制——通过 target 选项可以把输出降级到很低版本的 Node.js(如 target: 'node18'),因此用 tsdown 构建的库运行时并不会被锁死在 Node.js 22+。

技能文档给出的建议工作流是:若你的包需要支持 Node.js 18/20,在 CI 中用 Node.js 22+ 构建,并在要支持的低版本 Node.js 上(例如通过 matrix job 跑 Node 18/20/22)测试构建产物或打包后的 tarball。

安装技能:把 tsdown 知识注入编码代理

技能通过 skills CLI 安装(见 .agents/skills/tsdown/README.md):

# 安装全部 tsdown 技能(含迁移技能)
npx skills add rolldown/tsdown

# 只安装 tsdown 技能本身
npx skills add rolldown/tsdown --skill tsdown

第二条命令的 --skill tsdown 用于按需安装:默认安装会同时带上专用的迁移技能(tsdown-migrate,提供完整的选项映射、配置转换与排障指引),若你暂时不需要从 tsup 迁移,可以只安装核心技能。

仓库内 .agents/skills/tsdown/ 目录还包含 LICENSE.md(MIT)与 SYNC.md(记录来源 vendor/tsdown/skills/tsdown 及同步 Git SHA),说明该技能与上游保持同步。

技能知识地图:九个知识域的展开

README 的 "What's Included" 列出了技能覆盖的九大知识域,下面逐一展开其要点(每个主题在 .agents/skills/tsdown/references/ 下都有独立参考文档,路径随文标注)。

1. 核心概念

tsdown 基于 Rolldown 提供库打包的完整默认能力:能打包 .ts/.js 现代语法、自动生成 .d.ts、输出 esm/cjs/iife/umd 四种格式、处理 .json/.wasm/CSS 等资源,内置 tree shaking、压缩与 source map。详细入门见 .agents/skills/tsdown/references/guide-getting-started.md。

2. 配置文件

tsdown 会在当前目录及父目录自动查找配置文件,按顺序支持:tsdown.config.ts、.mts、.cts、.js、.mjs、.cjs、.json、无扩展名 tsdown.config,以及 package.json 中的 tsdown 字段(详见 .agents/skills/tsdown/references/option-config-file.md)。

配置优先级从高到低为:CLI 参数 > --config 指定的配置文件 > 自动发现的配置文件 > package.json 的 tsdown 字段 > 默认值。

配置文件支持四种形态:

  • TypeScript 配置(推荐,可类型检查与自动补全):
// tsdown.config.ts
import { defineConfig } from 'tsdown'

export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  clean: true,
})
  • 导出数组(多配置,每次配置独立构建):
export default defineConfig([
  { entry: 'src/index.ts', format: ['esm', 'cjs'], platform: 'node', dts: true },
  { entry: 'src/browser.ts', format: ['iife'], platform: 'browser', globalName: 'MyLib', minify: true },
])
  • 函数形式(动态配置,接收 options,含 watch 与传入的 CLI 标志):
export default defineConfig((options) => {
  const isDev = options.watch
  return {
    entry: ['src/index.ts'],
    format: ['esm', 'cjs'],
    minify: !isDev,
    sourcemap: isDev,
    clean: !isDev,
  }
})
  • Workspace/Monorepo(一个配置批量构建多个包):
export default defineConfig({
  workspace: 'packages/*',
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
})

配置加载器(--config-loader)默认 auto:优先使用运行时原生 TypeScript 支持(Node.js 22.18.0+、Bun、Deno),否则回退到 unrun;也可显式指定 native、tsx(tsx 是可选 peer 依赖,需手动 pnpm add -D tsx)或 unrun。--from-vite [vitest](实验性)可复用 Vite/Vitest 配置中的 resolve 与 plugins。--no-config 则完全忽略配置文件。

3. 构建选项

技能的构建选项知识域覆盖以下核心参数(参考文档见 .agents/skills/tsdown/references/ 下对应文件):

选项 用法示例 参考文档
入口点 entry: <a href="https://link.gitcode.com/i/c6fbc25804c739938026988e237e9fa3" target="_blank">'src/*.ts', '!**/*.test.ts'] [option-entry.md
输出格式 format: <a href="https://link.gitcode.com/i/8556a8fac05ff7fac91d459d5f234226" target="_blank">'esm', 'cjs', 'iife', 'umd'] [option-output-format.md
输出目录 outDir: 'dist'、outExtensions option-output-directory.md
类型声明 dts: true、dts: { sourcemap, compilerOptions, vue } option-dts.md
目标环境 target: 'es2020'、target: 'esnext' option-target.md
平台 platform: 'node'、'browser' option-platform.md
Tree shaking treeshake: true 及自定义选项 option-tree-shaking.md
压缩 minify: true、minify: 'dce-only' option-minification.md
Source map sourcemap: true、'inline'、'hidden' option-sourcemap.md
Watch 模式 watch: true 及 watch 选项 option-watch-mode.md
清理 clean: true 及清理模式 option-cleaning.md
日志级别 logLevel: 'silent'、failOnWarn: false option-log-level.md

几个需要展开的关键点:

**入口点(entry)**支持字符串、数组、对象与 glob 组合。对象形式的 key 即输出文件名,且 key 中可以带 * 占位符:{ 'lib/*': 'src/*.ts' } 会把 src/foo.ts 映射为 dist/lib/foo.js。数组值支持 ! 取反模式(如排除 !src/hooks/index.ts)。Windows 下路径务必使用正斜杠 /。与 unbundle: true 组合可保留目录结构(src/utils/helper.ts → dist/utils/helper.mjs)。

**输出格式(format)**默认 ESM,可选 esm/cjs/iife/umd。默认扩展名规则:ESM 为 .mjs(若 package.json 中 "type": "module" 则为 .js)、CJS 为 .cjs、IIFE 为 .iife.js、UMD 为 .umd.js。format 还支持对象形式按格式覆盖配置:

export default defineConfig({
  entry: ['src/index.ts'],
  format: {
    esm: { target: ['es2015'] },
    cjs: { target: ['node20'] },
  },
})

outExtensions 可自定义扩展名,但不会移除 .iife/.umd 段;如需完整自定义文件名需用 outputOptions.entryFileNames。

**类型声明(dts)**由 [rolldown-plugin-dts] 驱动,要求项目安装 TypeScript。两个值得注意的机制:

  • 若 package.json 含 types/typings 字段,DTS 生成自动启用;
  • 启用 tsconfig.json 中的 isolatedDeclarations: true 后走 oxc-transform 快速路径(推荐),否则回退到 TypeScript 编译器(可靠但更慢)。

高级选项包括 dts: { sourcemap: true }(声明 map,对 monorepo 有用)、compilerOptions 覆盖、vue: true(Vue 组件类型生成,需 vue-tsc)、oxc: true、tsconfig 指定路径、resolver: 'oxc' | 'tsc'(复杂第三方类型用 tsc)、cjsDefault、sideEffects。

**目标环境(target)**只影响语法降级,不提供运行时 polyfill。默认从 package.json 的 engines.node 自动读取(如 ">=18.0.0" 会设置 target: 'node18.0.0');没有该字段则等价于 target: false(不做变换)。支持 ES 版本(es2015…esnext)、浏览器版本(chrome100、safari18 等)与 Node.js 版本(node16、node20.18 等),也支持多目标数组。注意 Stage 3 装饰器目前不被 tsdown/Rolldown/Oxc 支持,仅支持 experimentalDecorators 的 Stage 2 装饰器。

**平台(platform)**决定模块解析与内建模块处理:node(默认,自动解析 fs/path 等内建,mainFields 为 ['main', 'module'])、browser(使用 Node 内建会警告,mainFields 为 ['browser', 'module', 'main'])、neutral(平台无关,只依赖 exports 字段,mainFields 默认 [],常需显式配置 inputOptions.resolve.mainFields)。CJS 格式固定使用 node 平台,无法更改。

**压缩(minify)**基于 Oxc minifier(当前处于 alpha)。支持 true(完整压缩)、false(默认关闭)、'dce-only'(只做死代码消除,输出保持可读)与 MinifyOptions 对象。CLI 的 --minify 只是布尔开关,'dce-only' 需在配置文件中使用。

Watch 模式默认监听所有入口文件、所有被导入文件以及配置文件(配置文件变更会触发带缓存清理的完整重启)。支持 --ignore-watch/watch.exclude 排除、--on-success 成功后执行命令,以及 r(手动重建)、q(退出)两个键盘快捷键。tsdown 不提供 stub 模式,watch 模式是官方推荐的快速开发替代方案。

4. 依赖处理

tsdown 的依赖策略(见 .agents/skills/tsdown/references/option-dependencies.md)默认行为是:

  • 自动外部化(不打包):dependencies、peerDependencies、optionalDependencies;
  • 条件打包(仅当被源码实际导入):devDependencies 与 phantom 依赖(在 node_modules 中但不在 package.json 中)。

四个覆盖选项集中在 deps 字段:

export default defineConfig({
  deps: {
    neverBundle: ['react', /^@myorg\//],   // 强制外部化(支持正则)
    alwaysBundle: ['some-package'],        // 强制打包
    onlyBundle: ['cac', 'bumpp'],          // 白名单,打包未列出的依赖会报错
    skipNodeModulesBundle: true,           // 跳过全部 node_modules(不可与 alwaysBundle 同用)
  },
})

deps.onlyBundle 三种取值行为:数组——只有匹配的依赖允许打包,其余报错;false——抑制所有关于打包依赖的警告;不设置(默认)——打包了任何 node_modules 依赖都会警告。注意 onlyBundle 需要把子依赖也列入清单,而不仅是顶层导入。

弃用选项迁移对照(技能文档明确列出):external → deps.neverBundle;noExternal → deps.alwaysBundle;inlineOnly → deps.onlyBundle;deps.onlyAllowBundle → deps.onlyBundle。声明文件(.d.ts)遵循与 JS 相同的打包逻辑,复杂第三方类型建议 dts: { resolver: 'tsc' }。

5. 输出增强

  • Shims(option-shims.md):shims: true 给 ESM 输出补上 __dirname/__filename;ESM 中使用 require 时自动注入 createRequire(import.meta.url);CJS 输出自动注入 import.meta.url/import.meta.dirname/import.meta.filename。未使用时会自动被 tree shaking 移除,无运行时开销。浏览器/neutral 平台不需要 shims。
  • CJS 默认导出(cjsDefault):默认 true,控制 CJS 的 default 导出处理。
  • 自动生成 exports(option-package-exports.md):exports: true 根据构建产物自动生成 package.json 的 exports 字段(types/import/require 三项)。默认不生成顶层 main/module/types,需要时用 exports: { legacy: true }。exports: { all: true } 会把全部输出文件加入 exports;devExports 支持开发期指向源码(pnpm/yarn 支持,npm 不支持);customExports(pkg, context) 可追加自定义映射(如 pkg['./package.json'] = './package.json')。
  • CSS 处理(option-css.md,实验性):全部由 @tsdown/css 提供,安装即自动启用;未安装时遇到 CSS 文件会报错。支持 Sass/Less/Stylus 预处理器(preprocessorOptions、additionalData)、Lightning CSS 语法降级(基于 target)、CSS Modules(.module.css 等,scopeBehaviour/generateScopedName/localsConvention)、代码分割(splitting: true,默认合并为 style.css)与 inject: true(JS 输出保留 CSS import)。css.transformer 可选 'lightningcss'(默认)或 'postcss' 两条互斥处理路径。
  • Unbundle 模式(option-unbundle.md):unbundle: true 保留目录结构、逐文件编译(bundleless/transpile-only),适合工具库、monorepo 共享包与调试;产物更大但构建更快,最终优化交给使用方的打包器。
  • Root 目录(root: 'src'):控制入口路径到输出路径的映射(类似 TypeScript 的 rootDir),默认取所有入口的公共基目录。
  • 可执行文件(exe: true,实验性):打包为 Node.js SEA 单文件可执行程序,要求 Node.js ≥ 25.5.0,Bun/Deno 不支持;跨平台需 @tsdown/exe,默认格式变为 CJS、关闭 DTS 与代码分割、仅支持单一入口。
  • 包校验(option-lint.md):publint: true 校验 package.json 字段与产物匹配(level: 'warning' | 'error' | 'suggestion');attw: true("Are the types wrong?")校验不同模块解析策略下的类型声明正确性(profile: 'strict' | 'node16' | 'esm-only',支持 ignoreRules)。两者都是可选依赖,需分别安装 publint 与 @arethetypeswrong/core,且要求项目目录存在 package.json。

6. 框架支持

技能覆盖 React、Vue、Solid、Svelte 组件库与 WASM:

  • React(recipe-react.md):Rolldown 原生支持 JSX/TSX,基础组件无需插件;默认 automatic JSX(React 17+,无需 import React),可用 inputOptions.transform.jsx: 'react' 切回 classic;React Compiler 通过 @rollup/plugin-babel + babel-plugin-react-compiler 接入;开发期 Fast Refresh 用 @vitejs/plugin-react(options.watch 时启用)。
  • Vue(recipe-vue.md):通过 unplugin-vue/rolldown 编译 SFC(template → render 函数、scoped styles、script setup),dts: { vue: true } 配合 vue-tsc 生成组件类型;务必 deps.neverBundle: ['vue'] 外部化 Vue,并把它放进 peerDependencies。
  • Solid:SolidJS JSX transform(recipe-solid.md)。
  • Svelte:组件库推荐以源码形式分发(recipe-svelte.md)。
  • WASM:通过 rolldown-plugin-wasm 引入(recipe-wasm.md)。

7. 高级特性

  • 插件(advanced-plugins.md):兼容四大生态——Rolldown 原生插件(全兼容)、Unplugin(多数可用,用 UnpluginPlugin.rolldown())、Rollup 插件(高兼容,可能有类型问题,用 @ts-expect-error 或 as any 处理)、Vite 插件(仅限不使用 Vite 专属 API 的插件,兼容性有限)。插件按定义顺序执行。
  • Hooks(advanced-hooks.md):三个生命周期钩子——build:prepare(每次构建会话一次)、build:before(每个格式一次,context 可变,可注入插件)、build:done(构建完成后,可访问 context.chunks)。基于 unjs/hookable,支持 hookOnce/removeHook/callHook 等。推荐:简单任务用 hooks,复杂扩展用插件。
  • 编程式 API(advanced-programmatic.md):import { build } from 'tsdown',await build(options),配置对象与配置文件完全一致;watch 模式未在 API 中暴露,需用 CLI(可 spawn('tsdown', ['--watch']))。
  • Rolldown 选项透传(advanced-rolldown-options.md):inputOptions/outputOptions 支持对象或函数形式(函数接收 (options, format)),用于 tsdown 未暴露的底层能力,如 outputOptions.legalComments = 'inline'、inputOptions.cwd。
  • CI 环境(advanced-ci.md):通过 CI 环境变量检测(非 0/false 即视为 CI)。dts、publint、attw、report、exports、unused、devtools、failOnWarn 均接受 CI 感知取值:true/false/'ci-only'/'local-only'。配置函数上下文还提供 ci 布尔值:
export default defineConfig((_, { ci }) => ({
  minify: ci,
  sourcemap: !ci,
}))

8. CLI 命令

CLI 标志映射规则(见 .agents/skills/tsdown/references/reference-cli.md):--foo 置 foo: true;--no-foo 置 foo: false;--foo.bar 置 foo: { bar: true };--format esm --format cjs 置 format: ['esm', 'cjs'];支持 camelCase 与 kebab-case 等价写法(--outDir ≡ --out-dir)。所有 CLI 标志均可写入配置文件,CLI 优先于配置。

常用组合:

# 基础构建
tsdown

# 库(ESM + CJS + 类型)
tsdown --format esm --format cjs --dts --clean

# 生产构建
tsdown --minify --clean --no-report

# 开发(watch)
tsdown --watch --sourcemap

# 浏览器 IIFE
tsdown --format iife --platform browser --minify

# Node.js CLI 工具
tsdown --format esm --platform node --shims

# 单文件可执行程序
tsdown src/cli.ts --exe

# Monorepo 包
tsdown --clean --dts --exports --publint

# 环境变量与资源拷贝
tsdown --env-file .env.production --env.BUILD_TIME=$(date +%s)
tsdown --copy public --copy assets --clean

其他值得注意的标志:--env.* 设置编译期环境变量(以 import.meta.env.* 或 process.env.* 访问)、--env-prefix(默认前缀 TSDOWN_)、--unused 检查未使用依赖、--debug [feat] 调试日志、-W/-F 的 workspace 过滤(支持正则 /^pkg-/)、--fail-on-warn(默认启用,--no-fail-on-warn 关闭)。

9. 从 tsup 迁移

tsdown 基于 Rolldown(Rust)而非 tsup 的 esbuild,迁移指南见 .agents/skills/tsdown/references/guide-migrate-from-tsup.md。一键迁移工具:

# 单包
npx tsdown-migrate

# Monorepo(支持 glob 与多目录)
npx tsdown-migrate packages/*
npx tsdown-migrate packages/foo packages/bar

# 预览而不修改文件
npx tsdown-migrate --dry-run

迁移前务必先提交代码变更。

默认值差异(最容易踩坑的三处):

选项 tsup tsdown
format ['cjs'] ['esm']
clean false true
dts false package.json 含 types/typings 时自动启用
target 手动 从 engines.node 自动读取

选项重命名:outExtension → outExtensions。输出文件名差异:IIFE 构建 tsdown 输出 [name].iife.js,tsup 通常输出 [name].global.js,可通过 outputOptions.entryFileNames: '[name].global.js' 保留旧名。

tsdown 新增特性:nodeProtocol: true | 'strip' | false 控制 node: 前缀(默认 false 保持原样);更好的 workspace 支持(workspace: 'packages/*')。迁移清单:备份代码 → 运行迁移工具 → 审查变更 → 更新 package.json 脚本(tsup → tsdown)→ 验证构建 → 微调配置。大部分 tsup 功能(多入口、多格式、DTS、source map、压缩、watch、外部依赖、tree shaking、shims、Rollup 兼容插件)均已支持。

技能的使用方式与示例提示词

安装后,Claude Code 等代理会在以下场景自动使用 tsdown 知识:

  • 构建 TypeScript/JavaScript 库;
  • 为库项目配置打包器;
  • 设置类型声明生成;
  • 多格式构建(ESM、CJS、IIFE、UMD);
  • 从 tsup 迁移;
  • 构建框架组件库。

README 提供了五条可直接使用的示例提示词:

Set up tsdown to build my TypeScript library with ESM and CJS formats
Configure tsdown to generate type declarations and bundle for browsers
Add React support to my tsdown config with Fast Refresh
Help me migrate from tsup to tsdown
Set up a monorepo build with tsdown workspace support

airi 仓库中的 tsdown 实战配置剖析

airi 仓库的 pnpm workspace 中,packages/ 下大量库包使用 tsdown 构建(脚本均为 "build": "tsdown",见各包 package.json),以下是几份有代表性的配置,正好覆盖技能知识域中的多个场景:

多入口 + 声明文件:packages/core-agent

packages/core-agent/tsdown.config.ts 展示了「单包多入口」的典型写法——主入口加两个子模块入口:

import { defineConfig } from 'tsdown'

export default defineConfig({
  entry: [
    'src/index.ts',
    'src/agents/spark-command/index.ts',
    'src/agents/spark-notify/index.ts',
  ],
  dts: true,
})

配合 packages/core-agent/package.json 中手写的 exports 字段("."、"./agents/spark-notify"、"./agents/spark-command",各含 types 与 default),可以看到 dts 生成的 dist/index.d.mts 与产物 dist/index.mjs 一一对应。这正对应技能中「入口点对象/数组」「DTS 自动启用(package.json 含 types 字段)」「exports 字段」三个知识点。

命名入口 + unbundle + copy + 插件:packages/i18n

packages/i18n/tsdown.config.ts 是一份信息量最大的配置,几乎把「输出增强」章节全部用上:

import Yaml from 'unplugin-yaml/rolldown'

import { defineConfig } from 'tsdown'

export default defineConfig({
  entry: {
    'index': 'src/index.ts',
    'locales/index': 'src/locales/index.ts',
    'locales/en/index': 'src/locales/en/index.ts',
    'locales/zh-Hans/index': 'src/locales/zh-Hans/index.ts',
  },
  copy: [
    { from: 'src/locales', to: 'dist/locales' },
  ],
  unbundle: true,
  plugins: [
    Yaml(),
  ],
})

要点解读:

  • 对象入口:key 即输出路径,locales/en/index 会输出为 dist/locales/en/index.mjs,与 packages/i18n/package.json 中 ./locales/en 等 exports 子路径对应;
  • unbundle: true:保留 src/locales/ 的目录结构,让每个语言包单独成模块,消费者可按需 import;
  • copy:把 YAML 语言资源原样拷贝到 dist/locales,支撑 "./locales/*.yaml" 这类 exports;
  • Unplugin 插件:unplugin-yaml/rolldown 正是技能「插件生态」中 Unplugin 路线(unplugin-* 的 rolldown 入口)的真实用例。

平台与 tree shaking:packages/model-driver-magic-live2d

packages/model-driver-magic-live2d/tsdown.config.ts 面向浏览器运行时:

export default defineConfig({
  entry: {
    index: 'src/index.ts',
  },
  dts: true,
  platform: 'browser',
  treeshake: true,
})

platform: 'browser' 让打包器按浏览器语义解析(mainFields 优先 browser 字段、使用 Node 内建时告警),treeshake: true 剔除未使用的导出,正对应技能「平台」「Tree shaking」两个知识域。

依赖外部化 + target:packages/vite-plugin-sherpaw

packages/vite-plugin-sherpaw/tsdown.config.ts 演示了插件类库的两条铁律——宿主依赖必须外部化、产物语法要贴合宿主版本:

export default defineConfig({
  entry: {
    index: 'src/index.ts',
    assets: 'src/assets.ts',
  },
  deps: {
    neverBundle: ['vite'],
  },
  target: 'node18',
  dts: true,
})

deps.neverBundle: ['vite'] 把 Vite 声明为外部依赖(由使用方提供,避免双实例问题);target: 'node18' 将产物语法降级到 Node.js 18 可执行——与技能「运行时要求」一节互相印证:tsdown 自身需 Node 22.18+,但产物可通过 target 支持更低的 Node.js。

sourcemap + unused:packages/server-sdk

packages/server-sdk/tsdown.config.ts 使用了 source map 与未使用依赖检查:

export default defineConfig({
  entry: [
    './src/index.ts',
    './src/utils/node/index.ts',
  ],
  sourcemap: true,
  unused: true,
  inlineOnly: false,
})

其中 inlineOnly 正是技能「依赖处理」一章列出的 tsup 弃用选项(应迁移为 deps.onlyBundle),可以作为从 tsup 迁移时配置审查的对照案例;unused: true 对应 CLI 的 --unused(未使用依赖检查),sourcemap: true 生成外部 .map 文件便于服务端调试。

相关技能与资料索引

技能 README 提到两个关联项:tsdown-migrate(从 tsup 迁移的专用技能,随 npx skills add rolldown/tsdown 一并安装,也可用 --skill tsdown-migrate 单独安装)与 .agents/skills/tsdown/SKILL.md(技能入口文件,包含运行时要求、快速开始、最佳实践与全部参考文档索引)。

references/ 目录是技能知识的最终载体,按主题索引如下:

结语:把技能变成可复用的构建惯例

tsdown 技能的价值不在于让代理"记住"文档,而在于把一套经过验证的库打包最佳实践固化成了可检索、可执行的知识:

  1. 始终生成类型声明:dts: true,并在 tsconfig.json 开启 isolatedDeclarations 换取极速 DTS;
  2. 外部化依赖:deps: { neverBundle: [/^react/, /^@myorg\//] },避免把框架或 workspace 包打进来;
  3. 启用 tree shaking 与压缩:生产构建 treeshake: true + minify: true;
  4. 按需 shims:Node.js 工具/CLI 用 shims: true,浏览器/neutral 平台保持关闭;
  5. 自动生成 exports:exports: true 并配合 publint: 'ci-only'、attw: 'ci-only' 在 CI 中校验;
  6. watch 模式开发:tsdown --watch,配合 onSuccess 跑测试或启动服务;
  7. 工具库用 unbundle:unbundle: true 保留目录结构,让使用者按需引入。

在 airi 仓库中,这些惯例已经在 packages/core-agent、packages/i18n、packages/model-driver-magic-live2d、packages/vite-plugin-sherpaw、packages/server-sdk 等包的 tsdown.config.ts 中落地。当你在仓库内新建一个 npm 库包时,直接以这些配置为模板,结合 .agents/skills/tsdown/references/ 下的选项文档微调,即可在 monorepo 中稳定地产出高质量、可发布的 TypeScript 库。

登录后查看全文
airi