跳到正文
豫言包管理
← 全部包

双宿主构建 0.1.0

豫言 · 可执行文件

构建浏览器或云工豫言 Wasm 应用及其宿主外壳;--自动 模式自读包描述、传递解析依赖、绑定操作系统接口并构建。

云工模式另生成 动态资源.mjs:它把宿主库的隔离入口、宿主桥和句柄桥源码以及值桥 Wasm 字节打包给 Dynamic Worker Loader;另附文件式程序的隔离运行入口 隔离运行客.mjs 与浏览器编译器宿主 编译宿主.mjs(内存文件系统与 执行模块),供[隔离运行接口](../../../豫言操作系统接口/隔离运行/规范.汉语.md)的云工适配使用。业务仍只需编译豫言源码;若要使用 Loader,许可文件需在 LOADER 下列出绑定名,并在 Wrangler 中配置 worker_loaders。同一 get 标识必须使用不变的代码和限额。

本工具用豫言编写。它将应用豫言源码编译为 WasmGC,按编译器核心的结构化表示直接写出值桥,并从浏览器或云工宿主库复制固定的 JS 外壳。JS 外壳仅加载 Wasm、传递宿主能力;应用行为仍在豫言中。

自动模式(推荐)

构建一个云工或浏览器应用只需要一条命令:工具自己读应用的包描述,传递解析依赖,为每个 豫言操作系统XXX 接口选择适配并绑定,生成包上下文,构建应用,最后封装接口清单。不必再手写包上下文,也不必逐个运行 yy豫言操作系统绑定。

node 豫言操作系统/宿主/节点/宿主.cjs yy双宿主构建.wasm --自动 <云工|浏览器> <应用目录> <输出目录> \
  [--包根 <目录>]… [--许可 <文件>|-] [--命名入口 <名>] [--编译器 <路径>] [--类型检查]

构建根:在“构建根”目录运行。构建根是含 库/(标准库与内置基础库)、豫言操作系统接口/、豫言操作系统/(适配/、宿主/、装载/),以及已构建的 yy4_bs.wasm(或 --编译器 指定的编译器)、yy豫言操作系统接口检查、yy豫言操作系统绑定、yy豫言操作系统装载包 的目录。语言仓根目录本身就是构建根,云仓的 dist/构建源码 也是。这些目录可以是指向语言仓的符号链接:工具用规范化(解析符号链接后)的物理路径生成包上下文,因为包上下文要求规范的绝对路径,且编译缓存按路径计,同一份源码只能以一个路径出现。

参数(选项可以写在位置参数之前、之间或之后):

  • 云工|浏览器:宿主模式。
  • 应用目录:含 入口。豫 与恰好一个包描述的目录。
  • 输出目录:产物目录;构建前会先删除(见“产物与临时文件”里的安全检查)。
  • --包根 <目录>:可重复,指定到哪些目录(递归)里找库包,只认 <包名>。包。豫。目录相对构建根,也可写绝对路径;同一文件经多个包根重复出现只算一个。
  • --许可 <文件>|-:云工模式的许可文件;缺省时取 <应用目录>/许可.json(存在时),否则不用;- 表示明确不用。浏览器模式不使用许可文件,给出文件会报错。
  • --命名入口 <名>:仅云工模式,同旧调用形式的第七个参数(须为 ASCII 标识符)。
  • --编译器 <路径>:缺省 ./yy4_bs.wasm;不含斜杠的名字会补 ./。
  • --类型检查:只对入口做类型检查(编译器带 --type-check-only --parallel -j 24,诊断直接打印到终端),不构建产物,不装载清单。
  • 编译器恒带 --parallel -j 24(构建并行度不低于二十)。--帮助 打印两种调用形式的用法。

做什么(按顺序):

  1. 应用目录须恰有一个 *。包。豫,读其名称、所有者与依赖;没有时,须恰有一个 *。包。豫.txt(语言仓一致性验证目录把包描述存成 .txt,免得被全仓库包发现当成包):此时把应用目录复制到 dist/.自动构建/<输出名>/应用,并把 .txt 改回原名,此后以副本为应用目录。
  2. 传递解析依赖:标准库 与内置基础库(单元测试、癸象工具、网页客户端、云工宿主、浏览器宿主)内置;豫言操作系统XXX 表示操作系统接口 XXX;其余依赖到各 --包根 里找恰一个 <名>。包。豫,找不到或多于一个都报错(写明包名、被谁依赖、已搜索的包根或全部候选),并递归解析它的依赖;环用已访问表截断。库与应用的排列是依赖在前、应用在末;接口按名字的字节序排列,与依赖声明顺序、包根顺序无关,产物可复现。所有包的所有者须为「豫言」,依赖须是平铺的名字列表,包名与接口名不得为空、.、..,也不得含斜杠、反斜杠、制表符与换行。
  3. 对每个接口 XXX:接口目录 豫言操作系统接口/XXX(恰有一个 *。接口。豫 模块),适配目录按宿主模式取第一个存在的:云工模式 豫言操作系统/适配/XXX云工、XXX,浏览器模式 XXX浏览器、XXX;先删旧的 dist/操作系统绑定/XXX,再运行 ./yy豫言操作系统绑定 <接口包描述> <适配包描述> <适配实现模块> dist/操作系统绑定/XXX。找不到适配时报错,并提示是否只存在另一宿主的适配。
  4. 生成包上下文到 dist/.自动构建/<输出名>/包上下文(一行一个包:标准库、各内置基础库、各接口绑定包、库、应用;路径都是规范绝对路径,字段以真制表符分隔)。
  5. 调老调用形式的同一函数构建(进程内,不另起本工具):<模式> <应用目录>/入口。豫 <输出目录> <编译器> <包上下文> <许可文件或-> 加可选的命名入口。
  6. 运行 ./yy豫言操作系统装载包 <输出目录> dist/操作系统绑定/<各接口>…,写入 接口要求组.json 与 宿主提供组.json。

产物与临时文件:

  • <输出目录>:先删后建。安全检查:输出目录最后一段不能是空、.、..;已存在的必须是目录;不能位于 dist/.自动构建 内;不能等于构建根、应用目录、任一包根,也不能是它们的上级目录。
  • dist/操作系统绑定/<接口名>/:接口绑定包,每次构建都重新绑定。
  • dist/.自动构建/<输出名>/:生成的 包上下文(可用来复查)与 .txt 描述时的 应用/ 副本。云仓与语言仓都已忽略 /dist/。

错误信息:一律中文并写明原因。包括:当前目录不是构建根;缺少工具或文件;应用目录没有或有多个包描述;包描述格式不对(带文件名与病因);找不到依赖包、有多个候选、名称或所有者不符;接口没有适配;输出目录不安全;外部命令失败(带命令行与退出码,编译失败还附编译器输出)。失败时退出码为 1。

与老调用形式的关系:老调用形式(下一节)不变,云仓构建程序仍在使用。自动模式最终调用同一个构建函数,同一包上下文下与老调用形式的整个输出目录逐字节相同;与手写配方的差别只有:直接读取工作树里的库源码(不再 rsync 到暂存)、接口清单里接口按名字排序、包上下文行序不同(行序不影响 程序.wasm)。

例子:

# 云工:云工作台用户目录持久对象(云仓,构建根里,包根用绝对路径)
node 豫言操作系统/宿主/节点/宿主.cjs yy双宿主构建.wasm --自动 云工 $C/应用/豫言云工作台/用户目录应用 dist/云用户目录 \
  --包根 $C/应用/豫言云工作台/库 --包根 $C/库
# 浏览器:包服务阅读页
node 豫言操作系统/宿主/节点/宿主.cjs yy双宿主构建.wasm --自动 浏览器 $C/应用/包管理服务/阅读应用 dist/阅读应用 --包根 $C/应用/包管理服务/库
# 语言仓一致性验证(.txt 描述,无需包根),产物 dist/日志一致性
node 豫言操作系统/宿主/节点/宿主.cjs yy双宿主构建.wasm --自动 云工 豫言操作系统/适配/日志/一致性验证/应用 dist/日志一致性

须知:编译缓存目录取决于编译器 .wasm 的路径与修改时间,多个构建同时使用同一编译器会共享缓存,也共用 dist/操作系统绑定,勿并发。已知限制:只支持所有者为「豫言」的包;依赖列表须是平铺名字;接口逐个绑定(不并行);编译失败时编译器的全部输出原样带回,较长。

构建本工具:在构建根里写一个只含标准库、单元测试、癸象工具与本包的包上下文(路径须为规范绝对路径,故用 pwd -P),再用稳定编译器编译(云仓构建程序也是这样构建它的):

R=$(pwd -P)
printf '豫构包上下文二\n豫言\t标准库\t%s/库/标准库/标准库。包。豫\n豫言\t单元测试\t%s/库/单元测试/单元测试。包。豫\t豫言\t标准库\n豫言\t癸象工具\t%s/库/癸象工具/癸象工具。包。豫\t豫言\t标准库\t豫言\t单元测试\n豫言\t双宿主构建\t%s/豫言操作系统/应用/双宿主构建/双宿主构建。包。豫\t豫言\t标准库\t豫言\t单元测试\t豫言\t癸象工具\n' $R $R $R $R > 双宿主构建上下文
node 豫言操作系统/宿主/节点/宿主.cjs yy_bs_stable.wasm 豫言操作系统/应用/双宿主构建/入口。豫 --package-context 双宿主构建上下文 --do-not-load-cache -o yy双宿主构建.wasm

单元测试(纯函数部分:包描述解析、依赖解析、包上下文生成、接口适配选择、命令行解析):在语言仓根目录运行 node 豫言操作系统/宿主/节点/宿主.cjs yy豫构.wasm 构建 双宿主构建 <测试名> --输出 yy双宿主构建测试.wasm,再用同一宿主运行产物。测试名依次是 文本工具。测试、包描述。测试、依赖解析。测试、上下文生成。测试、接口适配。测试、自动参数。测试、宿主构建。测试;例如 node 豫言操作系统/宿主/节点/宿主.cjs yy豫构.wasm 构建 双宿主构建 包描述。测试 --输出 yy双宿主构建包描述测试.wasm && node 豫言操作系统/宿主/节点/宿主.cjs yy双宿主构建包描述测试.wasm。也可用编译器直接编:node 豫言操作系统/宿主/节点/宿主.cjs yy3_bs.wasm 豫言操作系统/应用/双宿主构建/包描述。测试。豫 --package-context 双宿主构建上下文 --parallel -j 24 -o yy双宿主构建包描述测试.wasm,其中包上下文与下面构建本工具用的相同。

老调用形式

先构建 yy双宿主构建,然后从豫言仓库根运行:

node 豫言操作系统/宿主/节点/宿主.cjs yy双宿主构建.wasm 浏览器 应用/入口。豫 dist/浏览器 ./yy3_bs.wasm 包上下文 -
node 豫言操作系统/宿主/节点/宿主.cjs yy双宿主构建.wasm 云工 应用/入口。豫 dist/云工 ./yy3_bs.wasm 包上下文 许可.json
node 豫言操作系统/宿主/节点/宿主.cjs yy双宿主构建.wasm 云工 应用/入口。豫 dist/云工 ./yy3_bs.wasm 包上下文 许可.json CloudModel

许可.json 按绑定种类列出可用名称,例如 {"KV":["账户缓存"],"R2":["项目资源"],"D1":["项目数据库"],"SERVICE":["编译服务"],"DO":["项目对象"],"ASSETS":["ASSETS"],"QUEUE":["页面队列"],"EMAIL":["EMAIL"]}。浏览器模式传 -。云工模式产物的 入口.mjs 是 Wrangler 的 main,同一豫言 Wasm 可由 fetch 或 queue 事件调用;浏览器模式由页面导入 入口.mjs 并调用 启动豫言浏览器应用()。构建器编译应用时禁用旧缓存,避免共享工作树中的过期产物;它不创建 Wrangler 部署配置,也不修改云仓代码。

第七个参数可选,仅云工模式使用:指定一个 ASCII 标识符作为命名 WorkerEntrypoint 导出名。上例生成 CloudModel,其 fetch(Request) 以 service-fetch 事件进入同一豫言 Wasm;公开默认入口继续以 fetch 事件进入,由豫言分别处理。Wrangler 的 Service binding 可配置 {"binding":"内部服务","service":"当前Worker名","entrypoint":"CloudModel"}。Wrangler 4.129.0 本地同 Worker 绑定已验证公开默认路径与内部服务路径分离;非法别名会被构建器拒绝。自定义 RPC 方法、多命名入口和云端部署尚待补齐。Cloudflare 命名入口文档说明绑定配置。

浏览器模式还会复制 自动启动.mjs。页面直接写 <script type="module" src="/产物/自动启动.mjs?标识=应用根"></script> 即可启动,不需另写调用 JS;只有 id="应用根" 的元素存在时才加载 Wasm。省略 标识 时直接启动。真实 Chrome 已验证存在时执行豫言 Wasm、缺少标识时跳过且不请求 Wasm 文件。入口.mjs 的显式启动函数仍可用于需要自行控制生命周期的页面。

浏览器模式也复制 工作线程自动启动.mjs。将 Worker 的豫言程序另构建至页面产物子目录后,页面豫言可用 浏览器工作线程新建("./子目录/工作线程自动启动.mjs", "{}") 启动它。外壳在 Dedicated Worker 中加载同目录的 程序.wasm 与 值桥.wasm;Worker 业务须用豫言写,并调用 浏览器工作线程自身句柄、浏览器事件订阅选项、等待浏览器事件 及 浏览器工作线程向主线程发值。真实 Chrome 已验证两侧豫言 Wasm 的 ready 与回显往返。

云工模式的 入口.mjs 还导出通用 豫言持久对象 类,可在 Wrangler 的 Durable Object 绑定和 SQLite exports 中引用。类的 fetch、alarm 外层分派由宿主库完成,实际对象逻辑与持久数据读写由同一豫言 Wasm 执行;构建器仍不替应用生成 Wrangler 配置。

云工模式还会读取应用目录(入口。豫 所在目录)里的可选文件 执行配置.json,经 JSON 解析并规范化后写成产物 动态资源.mjs 的导出常量 执行配置,缺文件时写 {}(非法 JSON 使构建失败)。它只调整各事件种类的墙钟时限(如 {"事件时限毫秒":{"durable-alarm":900000}}),不属于 许可.json,也不改变许可的绑定种类结构;产物里的 入口.mjs 在加载时校验并使用它,非法配置使 Worker 加载失败。入口壳用命名空间导入读取该导出,所以新旧壳与新旧构建器可以混用(缺少该导出时按默认时限运行)。格式、默认值与上限见 豫言操作系统/宿主/云工/说明.汉语.md。

构建器调用编译器时恒带 --parallel -j 24(二十四路并行调度,用户要求构建并行度不低于二十),类型检查与最终链接的耗时明显缩短(实测应用类型检查由约 40 秒降到约 18 秒);同一编译缓存同一时刻只应由一次构建使用,勿并发运行多个 yy双宿主构建 共享缓存。

依赖

查看包配置

上传历史

当前上传修订:1 ·

  1. 上传修订 1
    下载 ZIP

包层级

父包:豫言操作系统工具

没有子包。