Wasm Component Model 构建期组合实操笔记:WAC CLI
1. Composition 在构建期到底做了什么
wac plug / wac compose 做的事情是:拿一个 primary 组件,把它的 imports 接到一个或多个 dependency 组件的 exports 上,最终产出一个新的 .wasm。
组合结果的语义有几点必须记牢:
- 新组件导出的东西 只跟 primary 一致,dependency 的导出不会冒出来。
- 新组件的 imports = dependency 的 imports(未被满足的)+ primary 自身未被满足的 imports。
- 组合是不对称的:primary 是“被满足方”,dependency 是“满足方”,调换角色会得到完全不同的结果。
2. 组合只能发生在“接口层”
如果 primary 组件直接 import 了某个函数(而不是一个 instance / world 接口),组合会直接失败,报错原文:
component
has a non-instance import named
所以:组件边界必须走 WIT 接口。任何直接 import "..." 函数(比如来自二进制链接的符号)的组件,都无法被 WAC 组合。这也是为什么“用组件模型拼原生 wasm 函数”这条路目前走不通。
3. 接口版本匹配是硬约束
组合时接口名是带版本的。test:mypackage 和 test:mypackage@0.1.0 是两个东西,wac 不会帮你做模糊匹配。
排查办法:用 wasm-tools component wit 直接看 .wasm 里嵌的 import/export 接口全名。
wasm-tools component wit validator-component.wasm
wasm-tools component wit regex-component.wasm
对比两边的 import / export 接口名(带不带 @version),不一致就老老实实改成同一版本再组合。
4. 简单场景:wac plug 一条命令
假设:
validator-component.wasm导出validator接口,import 了docs:regex/match@0.1.0;regex-component.wasm导出match接口。
一个主组件 + 一个依赖:
wac plug validator-component.wasm --plug regex-component.wasm -o composed.wasm
多个依赖并列:
wac plug path/to/component.wasm \
--plug path/to/dep1.wasm \
--plug path/to/dep2.wasm \
-o composed.wasm
局限性:wac plug 不处理传递依赖。如果 dep1 自己还有未满足的 import(例如还依赖 dep3),直接 wac plug 会报错或产出一个仍带 import 的组件。
解决办法:先把 dep1 和 dep3 组合一次,得到新的组件再作为 plug 喂给 wac plug。
wac plug dep1.wasm --plug dep3.wasm -o dep1-composed.wasm
wac plug primary.wasm --plug dep1-composed.wasm -o final.wasm
5. 复杂场景:用 WAC 语言 + wac compose
要描述任意组合关系(多个实例、显式绑定、指定导出入口),写一个 composition.wac:
// 声明依赖包的实例
package docs:composition
let validator = new docs:validator-impl;
let regex = new docs:regex-impl;
// primary 是 validator 实例
export validator;
然后执行:
wac compose \
--dep docs:regex-impl=regex-component.wasm \
--dep docs:validator-impl=validator-component.wasm \
-o composed.wasm \
composition.wac
这个方式能显式控制 dependency 的满足关系,能覆盖 wac plug 处理不了的传递依赖,因为你可以先声明 let x = new dep; let y = new dep2; 再决定谁给谁。
6. 什么情况下别用 WAC / 组合
- 组件里存在非接口 import(直接 import 函数),别试,必失败。
- 接口版本不一致还没法改(比如第三方二进制锁定版本),别硬组合,先对齐版本。
- 当你只需要“把两个组件链接起来”但不想承担 primary/dependency 语义时,别用
wac plug——它强制不对称,且只导出 primary 的接口。
7. 现状与判断
这套工具(WAC CLI)还处于早期阶段,来自 WebAssembly/component-model 仓库的 wac 子目录(以及官方 wac docs)。命令行为、错误信息、语义细节都可能变更。
我在实际使用中的判断:
- 单层依赖、接口清晰:
wac plug够用。 - 依赖链超过两层:直接用 WAC 语言描述依赖图,不要试图用多个
wac plug拼,除非你想在 shell 里维护一团乱麻。 - 版本不匹配:先用
wasm-tools component wit检查,别猜。