Decorators 与 externalHelpers 隐性兼容逻辑

为什么这两个点容易漏

decoratorsexternalHelpers 都不是 Rslib 的主功能,但它们属于“构建成功不代表发布后正确”的兼容点。

它们的代码不长,却影响历史 TypeScript 项目和 SWC helper 运行时依赖。

decorators 从 tsconfig 推断

composeDecoratorsConfig 会读取 tsconfig 的 experimentalDecorators。如果用户没有显式配置 Rsbuild decorators version,但 tsconfig 开了 experimentalDecorators,Rslib 会设置:

source: {
  decorators: {
    version: 'legacy',
  },
}

这适配大量旧 TypeScript 项目。

为什么只在用户没显式配置时生效

如果用户已经配置:

source: {
  decorators: {
    version: '2022-03',
  },
}

Rslib 不应该再用 tsconfig 覆盖。显式配置优先于推断。

这个逻辑体现的是“从 tsconfig 兼容历史默认,但不抢用户意图”。

externalHelpers 是什么

SWC 转换时可能生成 helper。默认情况下 helper 可以内联到产物中。用户开启:

externalHelpers: true;

表示希望从 @swc/helpers 引入 helper,而不是每个文件内联。

为什么要求声明 @swc/helpers

如果产物引用:

import { _extends } from '@swc/helpers/_/_extends';

但 package.json 没有声明 @swc/helpers,发布后消费者安装你的包时可能找不到这个依赖。

所以 Rslib 检查 package.json 的 dependencies 和 devDependencies,如果没找到 @swc/helpers 就报错。

严格说,发布运行时依赖更应该在 dependencies 中;代码目前检查 dependencies 和 devDependencies,是为了覆盖仓库或构建期场景,但维护者仍应提醒用户正确声明运行时依赖。

exe 下为什么禁用 externalHelpers

experiments.exe 要生成单文件可执行程序,不能依赖外部 @swc/helpers。因此有 exe 时,Rslib 会把 externalHelpers 当 false 处理。

这属于产物模型优先级:exe 的单文件目标高于 helper external 体积优化。

修改风险

Decorators 改动要检查:

  • tsconfig experimentalDecorators
  • 用户显式 decorators version。
  • legacy decorator 项目。

externalHelpers 改动要检查:

  • package.json 依赖声明。
  • ESM/CJS import。
  • bundle 和 bundleless。
  • exe。
  • 发布后消费者安装场景。