03 单文件构建脚本与平台分包


文档摘要

03 单文件构建脚本与平台分包 本节摘要:第 3 章我们讲了「启动脚本挑平台包」,这一节讲反面——单文件构建脚本怎么造出那些平台包。OpenCode 用构建工具的「编译(compile)模式」把 TypeScript 源码产成一个单文件原生二进制(内嵌 Web UI 和 workers),按一个目标矩阵(共 12 个变体)产出所有平台包。本节讲清这套构建机制,把「造包」和「挑包」连成完整闭环。 一、目标:单文件原生二进制 先明确构建目标。OpenCode 想要的是单文件原生二进制——一个独立可执行文件,不需要用户装运行时,拷贝到机器上就能跑。 为什么是单文件? 零依赖:用户不用装 Bun/Node,降低使用门槛。 启动快:原生二进制比解释执行快。 分发简单:一个文件,好分发、好版本管理。

03 单文件构建脚本与平台分包

本节摘要:第 3 章我们讲了「启动脚本挑平台包」,这一节讲反面——单文件构建脚本怎么造出那些平台包。OpenCode 用构建工具的「编译(compile)模式」把 TypeScript 源码产成一个单文件原生二进制(内嵌 Web UI 和 workers),按一个目标矩阵(共 12 个变体)产出所有平台包。本节讲清这套构建机制,把「造包」和「挑包」连成完整闭环。

一、目标:单文件原生二进制

先明确构建目标。OpenCode 想要的是单文件原生二进制——一个独立可执行文件,不需要用户装运行时,拷贝到机器上就能跑。

为什么是单文件?

  • 零依赖:用户不用装 Bun/Node,降低使用门槛。
  • 启动快:原生二进制比解释执行快。
  • 分发简单:一个文件,好分发、好版本管理。

但 OpenCode 源码是 TypeScript,还依赖一堆包,怎么变成单文件原生二进制?靠构建工具的「编译模式」。

二、编译模式:把一切打成一个二进制

构建工具(这里是 Bun)提供「编译(compile)模式」——它把源码 + 依赖 + 运行时全部编译进一个原生二进制:

TypeScript 源码 + 依赖包 + 运行时(Bun) ▼ compile 单文件原生二进制(可执行)

这个二进制里内嵌了运行时,所以用户机器上不需要装任何东西。这就是「单文件、零依赖」的实现方式。

三、内嵌 Web UI 和 workers

OpenCode 的单文件二进制不止含内核代码,还内嵌了 Web UI 和 workers:

  • Web UI:前端界面被打包进二进制(除非显式跳过)。这意味着不需要单独分发前端,二进制自带 UI。
  • tree-sitter worker:语法分析 worker 也被内联,保证代码解析能力。

内嵌的做法大致是:构建时先把 Web UI 构建成静态文件,再以「文件导入」形式生成一个虚拟入口,最终编译进二进制。这样二进制跑起来时,Web UI 直接从内部读取,不依赖外部文件。

💡 内嵌的价值:一个二进制就是完整产品——内核 + UI + workers 全在里面。用户下载一个文件,什么都有了。这是极致的分发体验。

四、目标矩阵:12 个变体

一个二进制不够——因为第 3 章说的平台差异(OS×架构×libc×AVX2),要发多个变体。OpenCode 的目标矩阵有 12 个变体:

平台 变体
Linux arm64 / x64 / x64-baseline / arm64-musl / x64-musl / x64-musl-baseline
macOS arm64 / x64 / x64-baseline
Windows arm64 / x64 / x64-baseline

每个变体对应一个平台包。构建脚本会按这个矩阵,为每个变体编译一个二进制:

build --single(当前平台) 或 build(全矩阵,产出 12 个变体)

--single 标志只构建当前平台(开发者本地用);全量构建产出所有 12 个变体(发布用)。

五、跨平台变量

不同变体有些细微差异(如 musl vs glibc),构建时通过变量 define 区分:

  • libc 类型(musl/gnu)
  • 版本号
  • 平台相关常量

这些变量在编译时注入,让同一份源码能编译出适应不同平台特性的二进制。

六、每个变体一份包描述

每个变体编译完后,写一份包描述(package.json),含 os/cpu/libc 字段:

{ "name": "opencode-linux-x64-baseline-musl", "os": ["linux"], "cpu": ["x64"], "libc": ["musl"] }

这些字段让 npm 能按平台选包——用户在 Linux x64 musl 机器上装时,npm 自动选这个包。这和第 3 章的「启动脚本挑包」连成闭环:

构建(本节):产出 12 个带平台描述的变体包 │ ▼ 发布到 npm │ 安装:用户机器上 npm 按平台描述选包 │ 启动(第 3 章):启动脚本探测平台,挑对包执行

七、冒烟测试与发布

构建完不是直接发布,先做冒烟测试——跑一下 --version,确认二进制能正常启动。通过后才发布:

  • Linux 打 tar.gz,其他打 zip
  • 发布到 GitHub release / npm

这种「构建 → 冒烟 → 发布」的流程,保证发布的二进制至少能跑起来。

八、本节要点回顾

  1. 目标是单文件原生二进制:零依赖、启动快、分发简单。
  2. compile 模式:源码+依赖+运行时全编译进一个二进制。
  3. 内嵌 Web UI + workers:一个二进制是完整产品(内核+UI+语法分析)。
  4. 目标矩阵 12 变体:Linux 6 个 / macOS 3 个 / Windows 3 个,覆盖平台差异。
  5. 跨平台变量:libc/版本等编译时注入,同源码出不同变体。
  6. 包描述带 os/cpu/libc:让 npm 按平台选包,与第 3 章启动脚本挑包闭环。
  7. 冒烟测试后发布:构建→跑 --version→发布,保证能跑。

构建讲清了,最后一节讲可观测性——运行起来后怎么看它。


发布者: 作者: 灏天文库 转发
评论区 (0)
U