实验性可执行文件系统

系统定位

experiments.exe 是 @rslib/core 的实验性能力,用于在 Node.js 库构建完成后,基于 Node SEA 生成单文件可执行程序。相关源码位于 packages/core/src/exe。

它不是通用应用打包器,而是建立在 Rslib bundle 产物之上:先由 Rspack 生成单入口 Node JS 文件,再用指定 Node binary 的 --build-sea 生成可执行文件。

核心文件

文件职责
index.ts解析和校验 exe 配置,向 environment 挂载 ExePlugin
plugin.ts在 Rspack 编译成功后生成可执行文件
build.ts创建 SEA 配置并调用 Node --build-sea
download.ts下载、校验、解压目标 Node binary
version.ts平台、架构、Node 版本规范化和支持性校验
utils.ts命令执行、输出路径、二进制版本读取、macOS 签名等工具

配置入口

LibConfig.experiments.exe 支持:

  • true:使用默认目标,即当前平台、当前架构、当前 Node 版本。
  • 对象配置:可指定 fileName、outputPath、targets、seaOptions。

targets 中每项可以是:

  • 字符串:用户提供的 Node binary 路径。
  • 对象:描述目标 platform、arch、nodeVersion。

约束条件

validateExeTargets 会强制以下条件:

约束原因
只支持 format: "esm" 或 "cjs"SEA 主文件只区分 module 和 commonjs
必须 bundle: true需要单个 JS 主文件作为 SEA main
必须 output.target = "node"可执行文件运行在 Node 环境
每个 lib 只支持单 entrySEA main 只能指向一个入口
当前运行时必须支持 SEA避免使用不支持 --build-sea 的 Node
ESM exe 不能启用 snapshot当前实现只允许 CJS 使用 snapshot

如果要生成多个可执行文件,应拆成多个 lib item,而不是一个 lib 多入口。

目标规范化

resolveExeTargets 将用户目标规范化为 NormalizedExeTarget:

  1. 读取当前平台、架构和 Node 版本。
  2. 对每个 target 补默认值。
  3. 字符串 target 解析为 customBinaryPath。
  4. 跨平台 target 自动禁用 useCodeCache 和 useSnapshot,因为这些能力绑定宿主运行时。
  5. 多 target 时添加 platform-arch-version suffix,避免输出文件互相覆盖。

Binary 解析与下载

download.ts 将“构建用 binary”和“可执行模板 binary”分开处理:

  • executableBinaryPath:最终要注入 SEA blob 的目标 Node binary,平台和架构跟目标一致。
  • builderBinaryPath:执行 --build-sea 的 Node binary,必须能在当前宿主机器运行,但版本要与模板 binary 一致。

如果目标就是当前平台、架构、版本,则两者都使用 process.execPath。否则会下载对应 Node release:

  1. 构造 Node archive URL。
  2. 下载 SHASUMS256.txt。
  3. 校验目标 archive 的 sha256。
  4. 下载 archive 到 cache。
  5. 解压 archive。
  6. 设置可执行权限。

下载过程有 in-flight promise 缓存,避免并发 target 重复下载同一 archive。

构建流程

buildExecutable 会创建临时目录,写入 sea-config.json,调用 builder binary 的 --build-sea。在 macOS 上生成后会尝试签名。临时目录最终会被删除。

SEA 配置映射

seaOptions 会映射到 Node SEA 配置:

seaOptionsSEA 字段
disableExperimentalSEAWarningdisableExperimentalSEAWarning,默认 true
useSnapshotuseSnapshot
useCodeCacheuseCodeCache
execArgvexecArgv
execArgvExtensionexecArgvExtension
assetsassets,路径相对 root 解析

format: "esm" 会生成 mainFormat: "module",format: "cjs" 会生成 mainFormat: "commonjs"。

维护检查点

  • 修改 exe 支持矩阵时,要同步 LibExperiments 类型注释、校验逻辑和集成测试。
  • 修改 binary 下载时,要保留 checksum 校验,不能只依赖下载成功。
  • 修改跨平台策略时,要注意 builder binary 与 executable binary 的平台差异。
  • 修改输出路径时,要检查多 target suffix、Windows .exe 后缀和用户自定义 fileName。
  • exe 测试较慢,仓库将其拆到 integration-exe 项目,CI 可以单独调度。