Node.js 集成 WebAssembly 实战:从 AssemblyScript 到模块实例化

作者:终端旅客时间:2026-10-30 19:28:08浏览:275

本文介绍如何在 Node.js 环境中使用 WebAssembly。通过 AssemblyScript 工具链生成 .wasm 模块,利用 Node.js 内置的 WebAssembly API 进行二进制文件加载与实例化。文章涵盖从环境搭建、代码编译到模块调用的完整流程,并简述了通过 Wasmtime 访问操作系统功能的扩展方案。

1、概述

首先,探讨WebAssembly作为高效工具的价值,并掌握其使用方法。

WebAssembly是一种高性能类汇编语言,支持从C/C++、Rust及AssemblyScript等语言编译。Chrome、Firefox、Safari、Edge及Node.js均已提供支持。

WebAssembly规范定义两种文件格式:扩展名为.wasm的二进制模块格式,以及扩展名为.wat的文本表示格式。

2、核心概念

  • 模块:编译后的WebAssembly二进制文件,即.wasm文件。
  • 内存:可调整大小的ArrayBuffer。
  • 表:未存储在内存中的可调整大小的引用类型数组。
  • 实例:模块及其内存、表和变量的实例化状态。

使用WebAssembly需具备.wasm二进制文件及通信API。Node.js通过全局WebAssembly对象提供必要API。

console.log(WebAssembly);

在浏览器中打印该对象,如下图所示:

1、概述

3、生成WebAssembly模块

生成WebAssembly二进制文件的方法包括:

  • 手工编写WebAssembly(.wat),并使用wabt等工具转换为二进制格式
  • 在C/C++应用程序中使用emscripten(https://emscripten.org/)
  • 在Rust应用程序中使用wasm-pack(https://rustwasm.github.io/wasm-pack/book/)
  • 若偏好类似TypeScript的体验,请使用AssemblyScript(https://www.assemblyscript.org/)

部分工具不仅生成二进制文件,还生成用于浏览器运行的JavaScript“粘合”代码及相应HTML文件。

4、应用方法

若熟悉TypeScript体验,可通过AssemblyScript进行尝试

1、首先安装AssemblyScript

npm install --save-dev assemblyscript

通过编译器对应的脚手架工具,快速生成推荐的目录结构和配置文件

npx asinit .

目录结构如下:

  • ./assembly 包含正在编译到WebAssembly的AssemblyScript源目录。
  • ./assembly/tsconfig.json TypeScript配置继承了建议的AssemblyScript设置。
  • ./assembly/index.ts 示例文件正在编译到WebAssembly中,以便开始使用。
  • ./build 生成存储编译的WebAssembly文件的工件目录。
  • ./build/.gitignore 从源代码管理中排除已编译二进制文件的Git配置。
  • ./asconfig.json 定义“调试”和“发布”目标的配置文件。
  • ./package.json 包含编译到WebAssembly所需命令的包信息。
  • ./tests/index.js 启动测试,以检查模块是否正常工作。
  • ./index.html 生成的html文件

3、打开,index.ts 我们在里面写了一个函数:

export function add(a: i32, b: i32): i32 {
 return a + b;
}

4、随后执行编译

npm run asbuild

获得WebAssembly模块后,即可使用Node.js WebAssembly对象进行实例化。

// 假设存在 release.wasm文件,该文件aad 包含一个添加2个提供参数的函数
async function instantiate(module, imports = {}) {
  const { exports } = await WebAssembly.instantiate(module, imports);
  return exports;
}
export const {
  memory,
  add
} = await (async url => instantiate(
  await (async () => {
    try { return await globalThis.WebAssembly.compileStreaming(globalThis.fetch(url)); }
    catch { return globalThis.WebAssembly.compile(await (await import("node:fs/promises")).readFile(url)); }
  })(), {
  }
))(new URL("release.wasm", import.meta.url));

5、打开index.html文件,查看结果:

<!DOCTYPE html>
<html lang="en">
<head>
  <script type="module"> 
    import { add } from "./build/release.js"; 
		document.body.innerText = add(1, 2);
	</script>
</head>
<body></body>
</html>

1、概述

或者,运行测试用例查看最终结果,如下所示:

1、概述

5、与操作系统交互

WebAssembly模块本身无法直接访问操作系统功能。

可使用第三方工具Wasmtime(https://docs.wasmtime.dev/)来访问此功能。

Wasmtime利用WASI(https://wasi.dev/) API来访问操作系统的功能。

至此关于Node.js使用WebAssembly的介绍结束,更多相关Node WebAssembly内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

作者最新文章