MoonBit 再获美国知名科技媒体关注:The New Stack 推出 MoonBit Wasm 组件教程

174 阅读5分钟

三次登上美国知名技术媒体!MoonBit 又因 WebAssembly 组件模型引发关注!

在海外技术社区的持续关注下,MoonBit 又一次登上了美国知名开发者媒体 The New Stack。这是 TNS 第三次报道 MoonBit。本篇文章以 “如何用 MoonBit 构建 WebAssembly Components” 为主题,从工具链、接口定义到 Wasm 文件生成,对 MoonBit 的技术能力做了详细的解读:thenewstack.io/how-to-buil…

以下为原文翻译

MoonBit 是一门现代化语言,也是一套工作流,旨在构建高效的 WebAssembly 项目;它同样可以编译到 JavaScript。我上一次关注 MoonBit 是在 2024 年 6 月,因此这次我想看看它在 Wasm 使用方面是否有所进展。(顺带一提:如果您仍然对WebAssembly的意义感到陌生,你不是一个人。)

现在,MoonBit 也可以在 WebAssembly 的组件模型运行(Web Component Model),我们稍后将对此进行探讨。我们将实现这一点,然后检查它是否有效。本文中只打算实现一个简单的加法方法。

MoonBit 语言快速回顾

在开始之前,先快速回顾一下 MoonBit 语言。

当然,从 Hello World 开始:

fn print_hello() -> Unit { 
 println("Hello, world!") 
}

唯一稍微让人意外的是 Unit ,但它其实只是 MoonBit 中等价于 void 的一类对象。

这是另一个例子:

fn add3(x : Int, y : Int, z : Int) -> Int { 
 x + y + z 
}

这是一个“top level”;需要注意的是,MoonBit 必须显式声明类型。如果你想更深入了解这门语言,可以查看官方教程。官方教程


WebAssembly 组件模型集成

我们关注的是 WebAssembly 的集成。MoonBit 与 WebAssembly 组件模型 协同工作,这减轻了实现基本功能时的痛苦。组件模型通常是语言项目的下一阶段,因为它们固定了接口、契约以及数据类型。

逻辑上,一个组件是可以包含核心模块和/或其他子组件的结构。组件使用 WebAssembly Interface Types(WIT)来描述其中模块和子组件的接口。如果这听起来过于学术化,不用担心,它在实际生产工具链中完全能正常工作。本文的内容主要基于 MoonBit 的 WebAssembly 组件文档

安装构建组件需要的工具链

在继续之前,我们需要 wit-bindgen CLI 工具,它用于生成兼容 WIT 的绑定文件;这个工具是基于 Rust 的,所以你需要安装 Cargo。只要安装 Rust 就能获得 Cargo:

Wit-bindgen

curl https://sh.rustup.rs -sSf | sh

(如果你使用 Homebrew 安装过 Rust,你可能需要确认是否让 rustup 来管理对 Rust 的更新。我之前没更新好导致了更多的问题,所以我建议卸载 brew 安装的版本。)

在此之前,你可以先输入 cargo 以确认你是否已经正确安装: 在这里插入图片描述

虽然版本有点旧,但还能用。现在安装绑定工具:

cargo install wit-bindgen-cli

你可能会收到提示,要求你把 cargo 的 bin 目录加入 PATH。我是在 MacBook 上安装,因此直接把它加入了 PATH。

然后安装用于组件的 Wasm 工具:

cargo install wasm-tools

接着安装 MoonBit 本体:

curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash

安装完成后,你需要运行一个新的 shell 或执行:

source ~/.zshrc

现在你就可以运行 Rust 开发的项目组织工具 moon 了。 在这里插入图片描述

这下我们就把 Moon 的整套工具都准备齐了。

使用 WIT 文件定义程序

在编写 MoonBit 代码之前,我们需要先创建一个 WIT 文件,用来声明我们将在 WebAssembly 组件世界中使用的接口。

创建 wit/world.wit 文件:

package docs:adder@0.1.0; 

interface add { 
  add: func(x: u32, y: u32) -> u32; 
} 
world adder { 
  export add; 
}

这段 WIT 声明了一个版本为 0.1.0docs:adder 包,并定义了名为 add 的接口,其中包含一个接收和返回 u32 的函数(在 MoonBit 中对应 UInt)。WIT 中的 world 是一个容器,用来放置所有组件需要的部分,这里只有一个 add 接口。

UInt :docs.moonbitlang.com/en/latest/l…

现在我们为 WIT 生成 MoonBit 结构:

wit-bindgen moonbit wit/world.wit --out-dir . \
    --derive-eq \
    --derive-show \
    --derive-error

生成后你应该会看到生成的 .mbt 文件。

在这里插入图片描述

您可能已经猜到 .mbt 后缀是 MoonBit 文件。但当然我们还没有真正写 MoonBit 代码。如果现在尝试构建 Wasm 目标,会收到大量警告。 在这里插入图片描述

查看生成的 stub,你会发现其中没有实际实现。

在这里插入图片描述

简单来说,stub 里并没有真正的实现,只是接口定义。即使使用我们上面最小的 MoonBit 教程,我们仍然可以轻松完成它:

在这里插入图片描述

主配置文件 gen/moon.pkg.json 会包含相关路径信息。

构建 WebAssembly 模块与组件

现在我们来构建主 WebAssembly 模块:

moon build --target wasm

构建后会生成新的 target 目录,其中包含 Wasm 文件。 在这里插入图片描述

检查一下 gen.wasm 是否有效: 在这里插入图片描述

很好,它是合法的 WebAssembly。现在我们需要在组件模型中正确地封装它:

wasm-tools component embed wit target/wasm/release/build/gen/gen.wasm \
  --encoding utf16 \
  --output adder.wasm

然后执行:

wasm-tools component new adder.wasm --output adder.component.wasm

此时生成的文件已不同于普通的 Wasm 模块。

在这里插入图片描述

我们可以使用 Wasmtime 来验证是否成功:

在这里插入图片描述

如果 Wasmtime 报错,可以从这里安装最新版本:

curl https://wasmtime.dev/install.sh -sSf | bash

你也可以使用更复杂的宿主程序来进一步验证 .wasm 是否正常运行。

docs.moonbitlang.com/zh-cn/lates…

总结

我本来是想看看 MoonBit 的进展,结果却发现了 WebAssembly 组件模型。这就是开发者的旅程——总有一座更高的山。

在未来的某个阶段,MoonBit 需要在对组件模型的直接支持方面投入更多工作;否则,这种偏学术化的复杂度将使 Wasm 始终难以获得更广泛的采用(或使其更趋近于 Rust 的生态)。然而,这种模式与其他基于 stub 的模型颇为相似——尽管以 WSDL 作为类比并非最恰当——但在成熟的工具链中,它们依然能够良好运作,即便是由LLM驱动的工具链亦是如此。

MoonBit 被收录入《Top Programming Languages of Late 2025》!

在 MysticMatrix 发布的 《Top Programming Languages of Late 2025》 一文中,MoonBit 与 Mojo、Rust 一同被列为 2025 年度值得关注的新兴语言之一。

在这里插入图片描述

非常感谢社区的支持,我们会继续提升编译器与工具链,为大家带来更好的开发体验!