Repository Wiki
zai-org/ZCode

桌面与远程资源准备及打包

本文说明 @zcode/desktop 的构建脚本如何在生产构建前准备本地运行资源与可选远程资源,并区分资源准备、构建与打包入口。

目的与范围

面向维护桌面构建和 CI 的开发者:重点是桌面包的脚本入口、prepare-runtime-assets.mjs 的分支及执行顺序,以及可见的环境开关。远程预构建资源的下载与打包算法、各原生辅助程序的内部实现、安装包签名和发布流水线不在本页范围内;它们由各自的脚本负责,本页不推断未读取的实现。若需理解远端资源内容,请从 prepare-prebuilds.mjs 入手;若需理解安装包构造,请参阅 bundle.mjs。

概述

桌面包把「准备资源」和「执行生产构建」分成两个脚本:build 先运行 prepare:runtime-assets,再运行 build:no-runtime-assets;后者运行 prepare:build-meta 与 run-production-build.mjs。bundle 则是单独的脚本入口,不能仅凭脚本声明断言它自动执行完整资源准备流程。脚本定义

资源准备器根据目标平台选择任务:未设置跳过开关时先准备远程资源;始终准备本地 agent bundle;按 native-search 发布计划、Windows 导入开关和 macOS 目标决定是否增加其他准备步骤。每一步通过 runCommand 启动 pnpm,并在 finally 中输出持续时间。准备器实现

架构

Loading diagram...

Source: package.json, prepare-runtime-assets.mjs

图中 Orchestrator 到可选任务的箭头表示条件调用,并非所有平台都会执行。图示 build 的脚本编排顺序;没有把独立的 bundle 误画成 build 的隐含下一步。

实现与执行顺序

入口的职责划分

入口已验证的行为适用场景
prepare:runtime-assets执行 scripts/prepare-runtime-assets.mjs单独准备桌面运行资源
prepare:remote-assets执行仓库级 scripts/prepare-prebuilds.mjs单独触发远端资源准备;其内部细节不在已读取源代码中
build:no-runtime-assets先准备构建元数据,再调用 run-production-build.mjs资源已由其他步骤准备时的构建入口
build先准备运行资源,再调用 build:no-runtime-assets完整桌面构建入口
bundle调用 scripts/bundle.mjs独立打包入口;其选项与实际产物需核对该脚本

上述入口均来自 桌面包脚本声明。仓库根目录另有 prepare:desktop-runtime 和 prepare:remote-assets 两个转发到桌面包的命令,以及 bundle:desktop 转发入口。根脚本对应声明

目标平台与条件任务

准备器用 getTargetPlatform() 获取 os 与 arch,传给 resolveNativeSearchReleasePlan;是否增加 prepare:native-search 由返回计划的 enabled 属性决定。Windows 浏览器导入辅助程序只有在目标为 win32 且环境变量严格等于字符串 1 时才加入;macOS 窗口边界辅助程序在目标为 darwin 时加入。注释说明后者缺少 swiftc 时由其自己的脚本处理跳过,本文不进一步推断其实现。平台选择与注释

javascript
1const target = getTargetPlatform(); 2const nativeSearchReleasePlan = resolveNativeSearchReleasePlan({ 3 platform: target.os, 4 arch: target.arch, 5}); 6// Windows Chrome 导入入口未启用,默认构建继续编译 helper 会增加 CI 时间和发布签名面。 7// 保留显式开关,后续恢复入口时仍可复用既有原生实现和供应链校验。 8const shouldPrepareWindowsBrowserImportHelper = 9 target.os === "win32" && process.env.ZCODE_ENABLE_WINDOWS_BROWSER_IMPORT === "1"; 10// CUA 权限浮窗的吸附数据源。仅 macOS;缺 swiftc 时脚本内部自行降级为跳过(浮窗 fail-open 11// 到屏幕底部,仍可用),所以无条件挂在 darwin 上不会让构建变脆。 12const shouldPrepareMacosWindowBounds = target.os === "darwin";

Source: prepare-runtime-assets.mjs

任务数组固定以 prepare:agent-bundle 开始,再依次拼接符合条件的 native-search、Windows 导入、macOS 窗口边界任务;注释区分本地 agent 的 JS bundle(由应用的 Electron Node runtime 执行)和远程跨平台原生二进制。native-search 的归档按注释随仓库分发,该步骤是本地解包校验,不需要下载源配置。资源角色与任务数组

javascript
1const localRuntimeScripts = [ 2 "prepare:agent-bundle", 3 ...(nativeSearchReleasePlan.enabled ? ["prepare:native-search"] : []), 4 ...(shouldPrepareWindowsBrowserImportHelper ? ["prepare:browser-import-helper"] : []), 5 ...(shouldPrepareMacosWindowBounds ? ["prepare:macos-window-bounds"] : []), 6];

Source: prepare-runtime-assets.mjs

核心流程

Loading diagram...

Source: prepare-runtime-assets.mjs

远端资源在本地任务循环之前执行,且只由 ZCODE_SKIP_REMOTE_ASSETS 控制是否跳过;跳过远端资源不等于跳过本地 agent 与平台相关步骤。runTimedPnpmScript 通过当前进程环境执行命令,工作目录固定为桌面包根目录;Windows 主机使用 pnpm.cmd,其他主机使用 pnpm。执行函数与分支 后续调用

用法示例

以下示例是项目实际脚本声明,不是臆造的命令组合。build 适用于需要资源准备的路径,build:no-runtime-assets 只承担元数据与生产构建;bundle 是分开的入口。

json
1"prepare:runtime-assets": "node scripts/prepare-runtime-assets.mjs", 2"prepare:remote-assets": "node ../../scripts/prepare-prebuilds.mjs", 3"build:no-runtime-assets": "pnpm prepare:build-meta && node scripts/run-production-build.mjs", 4"build": "pnpm prepare:runtime-assets && pnpm run build:no-runtime-assets", 5"bundle": "node scripts/bundle.mjs"

Source: package.json

在准备器内部,实际启动与计时逻辑如下;finally 确保命令失败时仍会记录结束耗时,并不表示失败会被吞掉。

javascript
1function runTimedPnpmScript(scriptName) { 2 const startMs = Date.now(); 3 console.log(`[ci][timer] prepare-runtime-assets:${scriptName} start`); 4 try { 5 runCommand(pnpmCommand, [scriptName], { 6 cwd: desktopRoot, 7 env: process.env, 8 }); 9 } finally { 10 console.log( 11 `[ci][timer] prepare-runtime-assets:${scriptName} end duration_ms=${Date.now() - startMs}`, 12 ); 13 } 14}

Source: prepare-runtime-assets.mjs

配置选项

选项 / 输入类型默认 / 未设置时作用
ZCODE_SKIP_REMOTE_ASSETS环境变量字符串不跳过严格等于 "1" 才跳过 prepare:remote-assets;注释指出 Windows 安装包构建任务无需 mock-cdn 远端资产时可避免串行跨平台资源准备耗时。
ZCODE_ENABLE_WINDOWS_BROWSER_IMPORT环境变量字符串不启用严格等于 "1" 且目标 OS 为 win32 时准备浏览器导入辅助程序。
getTargetPlatform() 的 os、arch函数返回的目标信息具体值由目标平台模块决定决定 native-search 发布计划及两种平台辅助任务;此页不推断其环境变量覆盖规则。
nativeSearchReleasePlan.enabled布尔条件由 resolveNativeSearchReleasePlan 返回决定是否运行 prepare:native-search。

证据:条件构造、跳过分支。不要将空值、true 或其他非 "1" 值视为开启开关。

脚本接口与失败边界

此能力主要通过包脚本而不是 HTTP API 暴露。脚本声明 提供 prepare:runtime-assets、prepare:remote-assets、build:no-runtime-assets、build、bundle。准备器内部的 runTimedPnpmScript(scriptName) 接收包脚本名称,调用 runCommand(pnpmCommand, [scriptName], { cwd: desktopRoot, env: process.env });函数没有显式返回值,抛错类型取决于未在此处展开的 runCommand 实现。调用实现

失败模式、并发与运维

  • 准备器使用同步顺序的调用写法:先远端任务,再逐一遍历本地任务;没有在本文件中并行调度或重试。执行段
  • try/finally 在命令结束或抛错时打印 [ci][timer] 耗时;没有 catch 或本地恢复分支。不要把日志出现理解为准备成功。计时函数
  • ZCODE_SKIP_REMOTE_ASSETS=1 只跳过远端准备并输出提示,本地步骤仍执行;该开关针对不需要 mock-cdn 远端资产的 Windows build job,使用前应确认自己的交付物是否需要远端资源。开关说明
  • 扩展本地准备步骤的明确挂载位置是 localRuntimeScripts;保持条件与目标平台匹配,并注意它们按照数组次序串行调用。子脚本内部是否下载、缓存或清理产物,在已读取的源代码中未核实。任务数组

相关链接

Sources

(2 files)
packages/desktop
packages/desktop/scripts