[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fLuJslR6Ajq6hRC9diOfDxS-KamvP7o2MrRtS5slmIYg":3},{"item":4,"related":47},{"id":5,"type":6,"title":7,"slug":8,"summary":9,"body":10,"coverUrl":11,"productScreenshots":12,"productLinks":13,"authorName":14,"authorUrl":15,"authorSubject":16,"category":17,"tags":22,"sourceLabel":35,"sourceName":36,"sourceUrl":37,"status":38,"seoTitle":39,"seoDescription":40,"canonicalUrl":41,"isFeatured":42,"sno":43,"sortOrder":44,"publishedAt":45,"updatedAt":46,"createdAt":46},"153fb92b-ccb1-4311-ad7c-d93b36ea2203","article","WebAssembly Component Model：不同语言写的模块如何拼在一起？","webassembly-component-model-wasi-explained","WebAssembly 不只是一个能运行的二进制文件。Component Model 通过接口、类型和能力权限，让不同语言编写的组件能够组合。本文从 WIT、WASI 0.2 和宿主运行时讲清组件模型的价值、权限边界与适用场景。","WebAssembly 最初给人的印象是“把 Rust、C 或 C++ 编译成一个 `.wasm` 文件，然后放进浏览器运行”。但当系统变大，单个模块很快就会遇到边界问题：不同语言之间怎么传字符串和列表？模块怎样访问文件和网络？多个模块如何安全地组合？\n\nWebAssembly Component Model 正在把 WebAssembly 从“可执行文件格式”推进成“可组合的组件接口”。它关心的不只是代码能不能跑，还关心不同语言、不同运行时和不同权限之间如何互相协作。\n\n## 先给结论：Component 是带接口的 Wasm 单元\n\n传统 Wasm module 暴露的是比较底层的函数和线性内存。宿主和模块之间要自己约定指针、字符串编码、内存分配和错误处理。\n\nComponent 则试图把这些约定提升为接口层。组件可以声明自己提供什么函数、接受什么数据、返回什么结果，以及需要哪些宿主能力。WASI 0.2 就是建立在 WebAssembly Component Model 之上的系统接口规范。[WASI 0.2 说明](https:\u002F\u002Fgithub.com\u002FWebAssembly\u002FWASI\u002Fblob\u002Fmain\u002Fspecifications\u002Fwasi-0.2.12\u002FOverview.md)\n\n可以把 module 理解成“能运行的一段机器码”，把 component 理解成“带明确插口的可组合软件包”。\n\n## 为什么需要 WIT\n\nComponent Model 生态里常见的接口描述语言是 WIT（Wasm Interface Types）。它不是某一种编程语言，而是一份跨语言的契约：定义类型、函数、错误和资源如何在组件边界传递。\n\n一个概念性的接口可能长这样：\n\n```wit\npackage foundit:search@1.0.0;\n\ninterface search {\n  record query {\n    text: string,\n    limit: u32,\n  }\n\n  search: func(input: query) -> result\u003Clist\u003Cstring>, string>;\n}\n```\n\n真正的语言绑定和工具链会把这份接口生成成 Rust、Go、Python 或 JavaScript 可以使用的类型。这样，调用方不必知道另一个组件内部如何分配内存，也不必手写一套语言相关的 FFI 胶水。\n\n## 组件如何组合\n\n一个真实系统可以由多个来源不同的组件组成：\n\n```mermaid\nflowchart LR\n    A[Rust 组件：文本解析] --> C[宿主运行时]\n    B[Go 组件：远程数据查询] --> C\n    C --> D[WASI 能力：时钟\u002F文件\u002F网络]\n    C --> E[JavaScript 或服务端应用]\n```\n\n组合并不意味着组件自动拥有所有权限。宿主运行时可以决定：给某个组件文件读权限，但不给网络权限；给另一个组件网络访问，但只允许访问指定域名。能力被显式传入，权限边界就比“所有代码共享一个进程”更容易审计。\n\n## WASI 不只是“浏览器之外的标准库”\n\nWASI 常被简化成“Wasm 的文件系统接口”。这个理解太窄了。WASI 的方向是为 WebAssembly 组件提供一组模块化、可组合的系统能力，例如输入输出、文件、网络、随机数、时钟以及异步相关的接口。\n\n它的重点不是复制某个操作系统的全部系统调用，而是把能力拆成可授予、可替换的接口。一个组件只需要声明“我需要读取配置文件”，宿主再决定给它真实文件、内存中的虚拟文件，还是拒绝访问。\n\n## 它和容器有什么区别\n\n两者都可以用来隔离代码，但抽象层不同：\n\n| 维度 | WebAssembly Component | 容器 |\n| --- | --- | --- |\n| 组合单位 | 函数、接口和组件 | 进程和文件系统镜像 |\n| 启动成本 | 通常更轻 | 通常更重 |\n| 权限模型 | 可按能力授予 | 依赖容器与宿主配置 |\n| 跨语言调用 | 通过接口契约组合 | 通常通过网络或进程通信 |\n| 适合场景 | 细粒度插件、边缘函数、嵌入式扩展 | 完整服务和系统级隔离 |\n\nComponent Model 并不是容器的替代品。一个大型服务仍然可能运行在容器里，而其中的插件、规则引擎或用户代码则以 Wasm component 的形式加载。\n\n## 真正的难点在生态成熟度\n\nComponent Model 解决了接口表达和组合方向，但工具链仍然在发展。实际项目需要确认：\n\n- 目标语言是否有稳定的组件编译与绑定工具；\n- 目标运行时是否支持需要的 WASI 版本；\n- 异步、资源句柄和错误类型能否跨语言保持一致；\n- 依赖的宿主能力是否在浏览器、边缘平台和服务端都存在。\n\n如果项目只是把一段计算放进浏览器，普通 Wasm 可能已经足够；如果项目需要动态加载插件、隔离不可信代码，或让多个语言生态共享一套接口，Component Model 才更有价值。\n\n## 一条实用的判断标准\n\n当你发现系统里出现大量“每种语言一套 FFI”“插件必须绑定某个宿主语言”“权限只能靠进程级隔离”时，可以认真评估 Component Model。\n\n一句话总结：**WebAssembly module 解决“代码怎么运行”，Component Model 进一步解决“代码怎样带着接口和权限组合”。**\n\n## 来源\n\n- [WebAssembly：WASI 与规范](https:\u002F\u002Fwebassembly.org\u002Fspecs\u002F)\n- [WASI 0.2.12 Overview](https:\u002F\u002Fgithub.com\u002FWebAssembly\u002FWASI\u002Fblob\u002Fmain\u002Fspecifications\u002Fwasi-0.2.12\u002FOverview.md)","\u002Fuploads\u002F2026-09-08\u002Fb44135d7-7561-477f-9edc-c52fd17b99f4.jpg",[],[],"Foundit","https:\u002F\u002Ffoundit.cn","foundit-ai-editorial",{"id":18,"name":19,"slug":20,"description":21},"6179d3b6-dc34-4483-9ded-3cd9f1b37a47","科普","abbreviation","介绍各领域新兴概念",[23,27,31],{"id":24,"name":25,"slug":26},"a202d639-99a6-488a-a712-4d4c6ffd7e15","开发","dev",{"id":28,"name":29,"slug":30},"7c76bfc2-f80f-4ee0-a95d-27bd8708b434","技术","slug",{"id":32,"name":33,"slug":34},"144abe77-0dc6-4f66-a176-20bddb1c0bfa","编程","coding","WebAssembly\u002FWASI 官方规范","WASI 0.2.12 Overview","https:\u002F\u002Fgithub.com\u002FWebAssembly\u002FWASI\u002Fblob\u002Fmain\u002Fspecifications\u002Fwasi-0.2.12\u002FOverview.md","published","WebAssembly Component Model 与 WASI 0.2 入门","解释 WebAssembly Component Model 如何通过 WIT 和 WASI 让不同语言的组件安全组合，并比较它与普通 Wasm 模块和容器的区别。",null,false,51,0,"2026-09-08T00:00:00.000Z","2026-09-08T03:19:21.154Z",[48,58,66],{"id":49,"type":6,"title":50,"slug":51,"summary":52,"coverUrl":53,"authorName":54,"sno":55,"publishedAt":56,"createdAt":57},"ea23e2ef-cc1b-4977-ad38-bf95b363c953","SQLite复兴：从一个文件到边缘数据库","sqlite-libsql-turso-edge-database","SQLite 是没有服务器、就是一个文件的嵌入式数据库，零运维、极低延迟。借助 libSQL \u002F Turso，它正走向「边缘 + 多副本」，让读多写少的应用全球低延迟。","https:\u002F\u002Foxqtewbrpuiouqqjrvdv.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fpublic-media\u002F2026-07-19\u002F611d83bb-2a21-4271-a183-155a89a5bb81.jpg","Foundit AI",70,"2026-07-17T00:00:00.000Z","2026-07-19T17:10:52.499Z",{"id":59,"type":6,"title":60,"slug":61,"summary":62,"coverUrl":63,"authorName":54,"sno":64,"publishedAt":56,"createdAt":65},"974096b9-8c0e-431e-bab6-8cd58e2af97f","Passkey通行密钥：为什么用指纹登录比密码更安全","passkeys-webauthn-passwordless-login","Passkey 基于 WebAuthn\u002FFIDO，用非对称加密让私钥不出设备、并与域名绑定，从原理上防钓鱼。","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1614064641938-3bbee52942c7?w=1200",71,"2026-07-19T17:10:50.027Z",{"id":67,"type":6,"title":68,"slug":69,"summary":70,"coverUrl":71,"authorName":14,"sno":72,"publishedAt":73,"createdAt":74},"54d83c94-d588-400d-9d13-42daa20331e2","CAS：文件的身份可以由内容决定","content-addressable-storage-ai-coding","内容寻址存储 CAS 用内容摘要识别文件和构建产物，解释 AI 编程工具、容器和缓存为什么能复用结果。","\u002Fuploads\u002F2026-09-14\u002F3fab23b3-8bcd-4a3b-bf5a-2ab895ce3a10.jpg",41,"2026-09-14T00:00:00.000Z","2026-09-14T15:01:41.114Z"]