Setup AssemblyScript - ytak-sagit/game-of-life-react GitHub Wiki

既存の Bun プロジェクトに作成

  1. ルート直下に wasm ディレクトリ作成
  2. cd wasm
  3. bun init
$ bun init
bun init helps you get started with a minimal project and tries to guess sensible defaults. Press ^C anytime to quit

package name (wasm): gol-rule-wasm
entry point (index.ts): 

Done! A package.json file was saved in the current directory.
 + index.ts
 + .gitignore
 + tsconfig.json (for editor auto-complete)
 + README.md

To get started, run:
  bun run index.ts
$
  1. bun add -d assemblyscript
$ bun add -d assemblyscript
bun add v1.1.25 (fe62a614)

installed [email protected] with binaries:
 - asc
 - asinit

3 packages installed [15.04s]
$ 
  1. bunx asinit .
$ bunx asinit .
Version: 0.27.29

This command will make sure that the following files exist in the project
directory '/app/wasm':

  ./assembly
  Directory holding the AssemblyScript sources being compiled to WebAssembly.

  ./assembly/tsconfig.json
  TypeScript configuration inheriting recommended AssemblyScript settings.

  ./assembly/index.ts
  Example entry file being compiled to WebAssembly to get you started.

  ./build
  Build artifact directory where compiled WebAssembly files are stored.

  ./build/.gitignore
  Git configuration that excludes compiled binaries from source control.

  ./asconfig.json
  Configuration file defining both a 'debug' and a 'release' target.

  ./package.json
  Package info containing the necessary commands to compile to WebAssembly.

  ./tests/index.js
  Stater test to check that the module is functioning.

  ./index.html
  Starter HTML file that loads the module in a browser.

The command will try to update existing files to match the correct settings
for this instance of the compiler in '/app/wasm/node_modules/assemblyscript'.

Do you want to proceed? [Y/n] Y

- Making sure that the project directory exists...
  Exists: /app/wasm

- Making sure that the 'assembly' directory exists...
  Created: /app/wasm/assembly

- Making sure that 'assembly/tsconfig.json' is set up...
  Created: /app/wasm/assembly/tsconfig.json

- Making sure that 'assembly/index.ts' exists...
  Created: /app/wasm/assembly/index.ts

- Making sure that the 'build' directory exists...
  Created: /app/wasm/build

- Making sure that 'build/.gitignore' is set up...
  Created: /app/wasm/build/.gitignore

- Making sure that 'package.json' contains the build commands...
  Updated: /app/wasm/package.json

- Making sure that 'asconfig.json' is set up...
  Created: /app/wasm/asconfig.json

- Making sure that the 'tests' directory exists...
  Created: /app/wasm/tests

- Making sure that 'tests/index.js' exists...
  Created: /app/wasm/tests/index.js

- Making sure that 'index.html' exists...
  Created: /app/wasm/index.html

Done!

Don't forget to install dependencies before you start:

  npm install

To edit the entry file, open 'assembly/index.ts' in your editor of choice.
Create as many additional files as necessary and use them as imports.

To build the entry file to WebAssembly when you are ready, run:

  npm run asbuild

Running the command above creates the following binaries incl. their respective
text format representations and source maps:

  ./build/debug.wasm
  ./build/debug.wasm.map
  ./build/debug.wat

  ^ The debuggable WebAssembly module as generated by the compiler.
    This one matches your sources exactly, without any optimizations.

  ./build/release.wasm
  ./build/release.wasm.map
  ./build/release.wat

  ^ The optimized WebAssembly module using default optimization settings.
    You can change the optimization settings in 'package.json'.

To run the tests, do:

  npm test

The AssemblyScript documentation covers all the details:

  https://www.assemblyscript.org

Have a nice day!
$ 
  1. bun install
    • 前stepのログ内で Don't forget と言われているので忘れずに
  2. wasm/package.jsonscripts 部分を bun コマンドへ書き換え
{
  "name": "gol-rule-wasm",
  "module": "index.ts",
  "type": "module",
  "devDependencies": {
    "@types/bun": "latest",
    "assemblyscript": "^0.27.29"
  },
  "peerDependencies": {
    "typescript": "^5.0.0"
  },
  "exports": {
    ".": {
      "import": "./build/release.js",
      "types": "./build/release.d.ts"
    }
  },
  "scripts": {
    "asbuild:debug": "asc assembly/index.ts --target debug",
    "asbuild:release": "asc assembly/index.ts --target release",
-   "asbuild": "npm run asbuild:debug && npm run asbuild:release",
-   "test": "node tests",
-   "start": "npx serve ."
+   "asbuild": "bun run asbuild:debug && bun run asbuild:release",
+   "start": "bunx serve ."
  }
}
  1. bun run asbuild
    • wasm/build ディレクトリ以下に、debugrelease でそれぞれ以下が作成されていればOK
      • *.js
      • *.wasm
      • *.d.ts
$ bun run asbuild
$ bun run asbuild:debug && bun run asbuild:release
$ asc assembly/index.ts --target debug
$ asc assembly/index.ts --target release
$ 
  1. bun run start
$ bun run start
$ bunx serve .

   ┌────────────────────────────────────────┐
   │                                        │
   │   Serving!                             │
   │                                        │
   │   - Local:    http://localhost:3000    │
   │   - Network:  http://172.18.0.2:3000   │
   │                                        │
   └────────────────────────────────────────┘


wasm/assembly/index.ts に、AssemblyScript のコードを書く

  • 今回は、gol-rule.ts を WebAssembly コードにする
  1. gol-rule.ts の内容を wasm/assembly/index.ts にコピペ
  2. 型を AssemblyScript の型へ書き換え
    • const はすべて型を明示
    • 真偽値は bool
    • 数値は、index, width, heighti32 へ。他は u8 へ(0/1の値しか持たないので)
    • Array, ReadonlyArray 型は Int16Array
    • 関数定義は const から function へ置き換え
    • 関数の戻り値を明示
  3. bun run asbuild:debug でコンパイルできるかチェック
  4. コンパイルエラーがないようであれば、bun run asbuild でリリースビルドも併せて実行
  5. src/utilswasm 以下へコピー
  6. gol-rule.test.tswasm/tests 以下へコピー
  7. テストデータと期待値の配列型を Int16Array へ修正
  8. bun test
    • 150ms 前後かかる...却って遅くなった

参考