Assemblyscript简介

AssemblyScript 是一个 TypeScriptWebAssembly 的编译器。

Assemblyscript官网:
WebAssemble官网:
WebAssemble - MDN:

使用脚手架创建Assemblyscript项目

首先创建一个目录用来存放AssemblyScript项目,再进入此目录执行以下命令:

  1. mkdir AssembleScriptDemos
  2. cd AssembleScriptDemos
  3. npm init
  4. npm install --save @assemblyscript/loader
  5. npm install --save-dev assemblyscript

初始化此项目:

  1. npx asinit .

编译:

  1. npm run asbuild

运行测试:

  1. npm test

不出意外,控制台输出:ok

项目目录解析

  • assembly存放AssembleScript的源码,入口文件是index.ts文件
  • build编译路径,生成untouched.wasmoptimized.wasm
  • tests测试文件路径
  • asconfig.jsonAssembleScript配置文件
  • index.js入口文件
  • package.json项目包配置

编译AssembleScript并测试

修改assembly/index.ts

  1. export function fib(n: i32): i32 {
  2. var a = 0, b = 1
  3. if (n > 0) {
  4. while (--n) {
  5. let t = a + b
  6. a = b
  7. b = t
  8. }
  9. return b
  10. }
  11. return a
  12. }
  13. export function add(a: i32, b: i32): i32 {
  14. return a + b;
  15. }
  16. export function sub(a: i32, b: i32): i32 {
  17. return a - b;
  18. }

修改tests/index.js

  1. const assert = require("assert");
  2. const myModule = require("..");
  3. let res = myModule.add(1, 2)
  4. console.log(res)
  5. assert.strictEqual(res, 3);
  6. console.log("ok");
  7. res = myModule.sub(1, 2)
  8. console.log(res)
  9. res = myModule.fib(10)
  10. console.log(res)

其中myModule是入口文件index.js

  1. const fs = require("fs");
  2. const loader = require("@assemblyscript/loader");
  3. const imports = {};
  4. const wasmModule = loader.instantiateSync(fs.readFileSync(__dirname + "/build/optimized.wasm"), imports);
  5. module.exports = wasmModule.exports;

可以看到,引入了optimized.wasm,并将其导出。

编译:

  1. npm run asbuild

运行测试:

  1. npm test

不出意外,控制台输出:

  1. 3
  2. ok
  3. -1
  4. 55

在html中加载wasm

通过运行命令npm run asbuild后,会在 build目录生成optimized.wasm文件,如果想要在html中引入,可以通过以下几种方式。

方式一:通过fetch引入

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <script>
  11. async function fetchAndInstantiate() {
  12. const response = await fetch("./build/optimized.wasm");
  13. const buffer = await response.arrayBuffer();
  14. const obj = await WebAssembly.instantiate(buffer);
  15. let exports = obj.instance.exports;
  16. console.log(exports.add(1, 2));
  17. console.log(exports.sub(1, 2));
  18. console.log(exports.fib(10));
  19. }
  20. fetchAndInstantiate()
  21. </script>
  22. </body>
  23. </html>

方式二:通过loader引入(ESM方式)

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <script type="module">
  11. import loader from "https://cdn.jsdelivr.net/npm/@assemblyscript/loader/index.js";
  12. loader.instantiate(
  13. // Binary to instantiate
  14. fetch("./build/optimized.wasm"),
  15. ).then(({ exports }) => {
  16. console.log(exports.add(1, 2))
  17. console.log(exports.sub(1, 2))
  18. console.log(exports.fib(10))
  19. })
  20. </script>
  21. </body>
  22. </html>

方式三:通过loader引入(UMD方式)

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. <!-- UMD -->
  9. <script src="https://cdn.jsdelivr.net/npm/@assemblyscript/loader/umd/index.js"></script>
  10. </head>
  11. <body>
  12. <script>
  13. // import loader from "@assemblyscript/loader"; // or require
  14. loader.instantiate(
  15. // Binary to instantiate
  16. fetch("./build/optimized.wasm"),
  17. ).then(({ exports }) => {
  18. console.log(exports.add(1, 2))
  19. console.log(exports.sub(1, 2))
  20. console.log(exports.fib(10))
  21. })
  22. </script>
  23. </body>
  24. </html>

参考:Using the loader

参考资料