实验性可执行文件系统

系统定位

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 版本。
  • 对象配置:可指定 fileNameoutputPathtargetsseaOptions

targets 中每项可以是:

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

约束条件

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 自动禁用 useCodeCacheuseSnapshot,因为这些能力绑定宿主运行时。
  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 可以单独调度。