Assemblyscript简介
AssemblyScript 是一个 TypeScript 到 WebAssembly 的编译器。
Assemblyscript官网:
WebAssemble官网:
WebAssemble - MDN:
使用脚手架创建Assemblyscript项目
首先创建一个目录用来存放AssemblyScript项目,再进入此目录执行以下命令:
mkdir AssembleScriptDemos
cd AssembleScriptDemos
npm init
npm install --save @assemblyscript/loader
npm install --save-dev assemblyscript
初始化此项目:
npx asinit .
编译:
npm run asbuild
运行测试:
npm test
不出意外,控制台输出:ok
项目目录解析
assembly
存放AssembleScript的源码,入口文件是index.ts
文件build
编译路径,生成untouched.wasm
和optimized.wasm
tests
测试文件路径asconfig.json
AssembleScript配置文件index.js
入口文件package.json
项目包配置
编译AssembleScript并测试
修改assembly/index.ts
:
export function fib(n: i32): i32 {
var a = 0, b = 1
if (n > 0) {
while (--n) {
let t = a + b
a = b
b = t
}
return b
}
return a
}
export function add(a: i32, b: i32): i32 {
return a + b;
}
export function sub(a: i32, b: i32): i32 {
return a - b;
}
修改tests/index.js
:
const assert = require("assert");
const myModule = require("..");
let res = myModule.add(1, 2)
console.log(res)
assert.strictEqual(res, 3);
console.log("ok");
res = myModule.sub(1, 2)
console.log(res)
res = myModule.fib(10)
console.log(res)
其中myModule
是入口文件index.js
const fs = require("fs");
const loader = require("@assemblyscript/loader");
const imports = {};
const wasmModule = loader.instantiateSync(fs.readFileSync(__dirname + "/build/optimized.wasm"), imports);
module.exports = wasmModule.exports;
可以看到,引入了optimized.wasm
,并将其导出。
编译:
npm run asbuild
运行测试:
npm test
不出意外,控制台输出:
3
ok
-1
55
在html中加载wasm
通过运行命令npm run asbuild
后,会在 build
目录生成optimized.wasm
文件,如果想要在html中引入,可以通过以下几种方式。
方式一:通过fetch引入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
async function fetchAndInstantiate() {
const response = await fetch("./build/optimized.wasm");
const buffer = await response.arrayBuffer();
const obj = await WebAssembly.instantiate(buffer);
let exports = obj.instance.exports;
console.log(exports.add(1, 2));
console.log(exports.sub(1, 2));
console.log(exports.fib(10));
}
fetchAndInstantiate()
</script>
</body>
</html>
方式二:通过loader引入(ESM方式)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="module">
import loader from "https://cdn.jsdelivr.net/npm/@assemblyscript/loader/index.js";
loader.instantiate(
// Binary to instantiate
fetch("./build/optimized.wasm"),
).then(({ exports }) => {
console.log(exports.add(1, 2))
console.log(exports.sub(1, 2))
console.log(exports.fib(10))
})
</script>
</body>
</html>
方式三:通过loader引入(UMD方式)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- UMD -->
<script src="https://cdn.jsdelivr.net/npm/@assemblyscript/loader/umd/index.js"></script>
</head>
<body>
<script>
// import loader from "@assemblyscript/loader"; // or require
loader.instantiate(
// Binary to instantiate
fetch("./build/optimized.wasm"),
).then(({ exports }) => {
console.log(exports.add(1, 2))
console.log(exports.sub(1, 2))
console.log(exports.fib(10))
})
</script>
</body>
</html>