首页
/ tsdown 的 CI 环境感知构建:`ci-only` 与 `local-only` 选项在 airi 仓库中的应用

tsdown 的 CI 环境感知构建:`ci-only` 与 `local-only` 选项在 airi 仓库中的应用

2026-09-07 16:56:11作者:袁立春Spencer

本文基于 airi 仓库内置的 tsdown 技能文档 advanced-ci.md,完整讲解 tsdown 如何自动检测 CI 环境,并通过 true / false / 'ci-only' / 'local-only' 四种取值让同一份构建配置在本地与 CI 中表现出不同行为。读完本文,你能够在自己的库构建中实现“本地快速迭代、CI 严格校验”的差异化流水线,并理解 airi 这类大型 monorepo 中 tsdown 配置与 GitHub Actions 的实际配合方式。

CI 环境检测原理

tsdown 通过 CI 环境变量判断当前是否运行在 CI 环境中。检测规则如下:

  • process.env.CI 被设置为**非 0 且非 false(忽略大小写)**的值时,CI 模式启用;
  • CI=0CI=falseCI=FALSE 均视为未启用 CI 模式,按本地构建处理;
  • 主流 CI 平台(GitHub Actions、GitLab CI 等)都会自动注入 CI=true,因此通常无需手动设置。

这一判断结果会作为 ci 布尔值传入配置函数的上下文(见下文“配置函数”一节),同时驱动所有 CI-aware 选项的取值解析。

CI 感知取值(CI-Aware Values)

tsdown 中多个选项不局限于 boolean,而是接受一种“CI 感知字符串”。四种取值的语义如下:

取值 行为
true 始终启用(本地与 CI 都执行)
false 始终禁用
'ci-only' 仅在 CI 中启用,本地禁用
'local-only' 仅在本地启用,CI 中禁用

这套设计的核心动机是构建速度与质量校验的分离:DTS 生成、包校验(publint / attw)等步骤在本地开发时往往拖慢反馈循环,而它们恰恰是发布前最值得做的检查;反之,本地开发更需要 source map、更宽松的警告策略等体验优先的设置。

支持 CI 感知取值的选项

以下选项支持上表的 CI 感知字符串:

  • dts — TypeScript 声明文件(.d.ts)生成,底层由 option-dts.md 描述;
  • publint — 校验 package.jsonexports / main / types 等字段与实际产物是否一致;
  • attw — Are The Types Wrong? 校验,验证声明文件在 node10 / node16 / bundler 等模块解析策略下是否正确;
  • report — Bundle 体积报告;
  • exports — 自动生成 package.jsonexports 字段;
  • unused — 未使用依赖检查;
  • devtools — DevTools 集成;
  • failOnWarn — 遇到警告时使构建失败,默认值为 false(详见 option-log-level.md)。

其中 publintattw 的配置细节(levelprofileignoreRules 等参数)在 option-lint.md 中有完整说明,二者均为可选依赖:需要先安装 publint@arethetypeswrong/core 才生效。

三种使用形式

形式一:字符串形式(最简洁)

对于取值本身就是开关的选项,直接写 CI 感知字符串:

export default defineConfig({
  dts: 'local-only',        // 本地生成 DTS,CI 中跳过以加速构建
  publint: 'ci-only',       // 仅在 CI 中运行 publint 包校验
  failOnWarn: 'ci-only',    // 仅 CI 中遇到警告即失败(opt-in)
})

dts: 'local-only' 是一个值得注意的组合:声明文件供 IDE 与下游类型检查使用,本地保留它能让开发体验完整;而 CI 打包发布场景若已有独立的类型检查 job,则可以跳过 DTS 节省时间。

形式二:对象形式(带参数)

当选项接受配置对象时,把 enabled 字段设为 CI 感知取值,其余参数照常配置:

export default defineConfig({
  publint: {
    enabled: 'ci-only',
    level: 'error',
  },
  attw: {
    enabled: 'ci-only',
    profile: 'node16',
  },
})

对象形式的好处是校验规则始终写死在配置里,只是执行时机受环境控制。例如 attw.profile: 'node16' 表示忽略 node10 解析失败的宽容策略,无论本地还是 CI 语义一致,仅由 enabled: 'ci-only' 决定何时真正运行。

形式三:配置函数(显式拿到 ci 布尔值)

配置函数形式的回调会接收上下文参数,其中包含 ci 布尔值,可以基于它派生任意其他选项:

export default defineConfig((_, { ci }) => ({
  minify: ci,
  sourcemap: !ci,
}))

这是对 CI 感知字符串的通用补充:凡是 minifysourcemap 这类本身不支持 CI 感知字符串的选项,都可以借助 ci 布尔值实现等价的分环境行为。前两个参数分别为 CLI 传入的选项对象与环境上下文,ciCI 环境变量解析后的结果。

典型的 CI 配置

将上述能力组合起来,文档给出的“发布前严格、本地宽松”的典型配置是:

export default defineConfig({
  entry: 'src/index.ts',
  format: ['esm', 'cjs'],
  dts: true,
  failOnWarn: 'ci-only',
  publint: 'ci-only',
  attw: 'ci-only',
})

其运行效果:

  • 本地:正常产出 ESM/CJS 与 DTS,警告只提示不失败,不跑 publint / attw,反馈最快;
  • CI:产出相同,但任何警告都会使构建失败,且包结构(publint)与类型声明(attw)都会接受校验——这两项正是“打包错误在用户安装时才暴露”这类问题最有效的拦截点。

在 airi 仓库中的实际应用

airi 是一个 pnpm + Turborepo 组织的多包 monorepo(package.jsonbuild:packages 通过 turbo run build -F="./packages/*" 统一调度),仓库中 packages/ 下大量子包使用 tsdown 构建。从源码结构看,仓库内的 tsdown 配置以静态对象形式为主,普遍开启了 sourcemapunused(未使用依赖检查),例如:

这说明两类环境差异策略在 airi 中是分层落地的:

  1. CI 平台级差异由 GitHub Actions 工作流承担。.github/workflows/ci.yml 定义了 lintbuild-testunit-testtypecheckcheck-provenance 五个 job,其中 build-test 用 matrix 分别构建 stage-web、stage-tamagotchi 等应用,并固定 node@26.7.0 运行时;GitHub Actions 运行器自动注入 CI=true,因此 tsdown 侧所有 ci-only 选项在该流程中会全部生效,无需在 YAML 里做任何额外声明。
  2. 包构建级差异由 tsdown 配置承担。airi 仓库当前的 tsdown.config.ts 多为显式布尔值(如 dts: true),未直接使用 'ci-only' / 'local-only' 字符串——从源码结构看,仓库把“严格化”主要放在了独立的 typecheck / lint job 与 unused: true 这类轻量检查上,而把重量级的 publint / attw 校验留给发布流程(.github/workflows/release-pkg.yaml)。

对于想在 airi 风格仓库中复现文档典型配置的开发者,推荐路径是:在包级 tsdown.config.ts 中加入 publint: 'ci-only'attw: 'ci-only',并安装对应的可选依赖;本地 pnpm build 不受影响,CI 中则自动获得发布前校验。

注意事项与适用前提

  • publint / attw 需要项目目录下存在 package.json,且分别依赖 publint@arethetypeswrong/core 两个 devDependency,二者都缺失时选项不会生效;
  • failOnWarn 默认是 false,写成 'ci-only' 属于显式 opt-in 的严格化,建议在包结构稳定后再开启,避免历史警告直接导致 CI 红灯;
  • 配置函数中的 ci 布尔值与 CI 环境变量解析规则完全一致(非 0 / 非 false 即视为 CI),因此本地可用 CI=1 pnpm build 快速预演 CI 行为,无需真的推到远端;
  • 本文结论基于 airi 仓库内置的 tsdown 技能文档(.agents/skills/tsdown/references/ 目录)及其 tsdown.config.ts 实际配置;不同版本的 tsdown 选项集合可能不同,请以项目 lockfile 锁定的版本为准。

小结

tsdown 的 CI 环境支持本质上是一套“一份配置、两套行为”的构建策略:通过 CI 环境变量检测运行环境,用 true / false / 'ci-only' / 'local-only' 四种取值控制 dtspublintattwreportexportsunuseddevtoolsfailOnWarn 等选项的分环境启用,并允许在配置函数中直接读取 ci 布尔值派生 minifysourcemap 等其他行为。在 airi 这类 pnpm + Turborepo monorepo 中,这套机制与 GitHub Actions 的 CI=true 注入天然契合,让本地开发保持快速反馈、CI 流水线承担发布前校验,是库构建工程化中成本很低但收益明确的做法。

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

项目优选

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