Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Wasmのエコシステムを使った ツール作成方法

Avatar for asuka asuka
October 11, 2025

Wasmのエコシステムを使った ツール作成方法

Avatar for asuka

asuka

October 11, 2025
Tweet

More Decks by asuka

Other Decks in Technology

Transcript

  1. WHOAMI 2 name = asuka fav = Wasm [org] name

    = 株式会社モニクル role = SWE [sns] X = @a_skua GitHub = @a-skua Bluesky = @askua.dev
  2. 3 Go Conference 2025 Pure Goで体験するWasmの未来 - Speaker Deck •

    Wasmを使って安全にツールを実行できる • コンテナレジストリを経由してWasmを配布できる
  3. GOOS=wasip2 GOARCH=wasm 6 Go 1.21〜 • GOOSwasip1 GOARCH=wasm tinygoでは先行してWASI 0.2をサポートしている

    • GOOSwasip2 GOARCH=wasm WASI - Wasmを汎用バイナリとして利用するためのAPI仕様 WASI 0.1 (=wasip1 - POSIX APIを参考に策定 / ネットワークは未サポート WASI 0.2 (=wasip2 - Wasmコンポーネントモデルをベースに再設計 2018年 8月 G o 1.11 リ リ ー ス W asm サ ポ ー ト 2019年 W A SI 0.1 リ リ ー ス 2023年 8月 G o 1.21 リ リ ー ス W A SI 0.1 サ ポ ー ト 2024年 1月 W A SI 0.2 リ リ ー ス 2024年 8月 W A SI 0.2.1 リ リ ー ス W asm O C I A rtifact layout 2025年 W A SI 0.3 リ リ ー ス ? 2025年 2月 G o 1.24 リ リ ー ス W A SI 0.1 リ ア ク タ ー モ ジ ュ ー ル サ ポ ー ト
  4. GOOS=wasip2 GOARCH=wasm 7 Go 1.21〜 • GOOSwasip1 GOARCH=wasm tinygoでは先行してWASI 0.2をサポートしている

    • GOOSwasip2 GOARCH=wasm WASI - Wasmを汎用バイナリとして利用するためのAPI仕様 WASI 0.1 (=wasip1 - POSIX APIを参考に策定 / ネットワークは未サポート WASI 0.2 (=wasip2 - Wasmコンポーネントモデルをベースに再設計 2018年 8月 G o 1.11 リ リ ー ス W asm サ ポ ー ト 2019年 W A SI 0.1 リ リ ー ス 2023年 8月 G o 1.21 リ リ ー ス W A SI 0.1 サ ポ ー ト 2024年 1月 W A SI 0.2 リ リ ー ス 2024年 8月 W A SI 0.2.1 リ リ ー ス W asm O C I A rtifact layout 2025年 W A SI 0.3 リ リ ー ス ? 2025年 2月 G o 1.24 リ リ ー ス W A SI 0.1 リ ア ク タ ー モ ジ ュ ー ル サ ポ ー ト e.g.$ cat hello.go package main import ( "fmt" ) func main() { fmt.Println("Hello, 世界!") } e.g.$ GOOS=wasip2 GOARCH=wasm \ > tinygo build -o hello.wasm hello.go e.g.$ wasmtime run hello.wasm Hello, 世界!
  5. GOOS=wasip2 GOARCH=wasm 8 WASI 0.2の特徴 • コンポーネントモデルの採用 • ネットワーク対応 WASI

    - Wasmを汎用バイナリとして利用するためのAPI仕様 WASI 0.1 (=wasip1 - POSIX APIを参考に策定 / ネットワークは未サポート WASI 0.2 (=wasip2 - Wasmコンポーネントモデルをベースに再設計 2018年 8月 G o 1.11 リ リ ー ス W asm サ ポ ー ト 2019年 W A SI 0.1 リ リ ー ス 2023年 8月 G o 1.21 リ リ ー ス W A SI 0.1 サ ポ ー ト 2024年 1月 W A SI 0.2 リ リ ー ス 2024年 8月 W A SI 0.2.1 リ リ ー ス W asm O C I A rtifact layout 2025年 W A SI 0.3 リ リ ー ス ? 2025年 2月 G o 1.24 リ リ ー ス W A SI 0.1 リ ア ク タ ー モ ジ ュ ー ル サ ポ ー ト
  6. コンポーネントモデルとWIT コンポーネントモデル • 複数のWasmモジュールを1つのコンポーネントとしてまとめるための仕様 • WITIDLを使ってインターフェースを定義 (like Protocol Buffers) 10

    interface calc { eval: func(exp: string) -> result<s32, error>; } world a { import calc; export wasi:cli/run; } world b { export calc; } e.g. Rustで実装 e.g. Goで実装
  7. コンポーネントモデルとWIT コンポーネントモデル • 複数のWasmモジュールを1つのコンポーネントとしてまとめるための仕様 • WITIDLを使ってインターフェースを定義 (like Protocol Buffers) 11

    interface calc { eval: func(exp: string) -> result<s32, error>; } world a { import calc; export wasi:cli/run; } world b { export calc; } e.g. Rustで実装 e.g. Goで実装 e.g.$ cat foo.go package main import ( "go.bytecodealliance.org/cm" "example.com/component/gen/example/root/calc" ) func init() { calc.Exports.Eval = func(exp string) cm.Result[string, int32, string] { panic("TODO") } } func main() {} ptrとlenではなく,stringを扱えるのも特徴の1つ
  8. ネットワーク 13 WASI 0.2の特徴 • ネットワーク対応 • コンポーネントモデルの採用 WASI -

    Wasmを汎用バイナリとして利用するためのAPI仕様 WASI 0.1 (=wasip1 - POSIX APIを参考に策定 / ネットワークは未サポート WASI 0.2 (=wasip2 - Wasmコンポーネントモデルをベースに再設計 2018年 8月 G o 1.11 リ リ ー ス W asm サ ポ ー ト 2019年 W A SI 0.1 リ リ ー ス 2023年 8月 G o 1.21 リ リ ー ス W A SI 0.1 サ ポ ー ト 2024年 1月 W A SI 0.2 リ リ ー ス 2024年 8月 W A SI 0.2.1 リ リ ー ス W asm O C I A rtifact layout 2025年 W A SI 0.3 リ リ ー ス ? 2025年 2月 G o 1.24 リ リ ー ス W A SI 0.1 リ ア ク タ ー モ ジ ュ ー ル サ ポ ー ト e.g.$ cat http-server.go package main import ( "fmt" "net/http" ) func handle(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, 世界!") } func main() { http.HandleFunc("/", handle) fmt.Println("Starting server on :8080") if err := http.ListenAndServe(":8080", nil); err != nil { fmt.Println("Error starting server:", err) } } 標準パッケージはネットワークをサポートしていない GOOS=wasip2 GOARCH=wasmだけだと動かない
  9. ネットワーク 14 WASI 0.2の特徴 • コンポーネントモデルの採用 • ネットワーク対応 WASI -

    Wasmを汎用バイナリとして利用するためのAPI仕様 WASI 0.1 (=wasip1 - POSIX APIを参考に策定 / ネットワークは未サポート WASI 0.2 (=wasip2 - Wasmコンポーネントモデルをベースに再設計 2018年 8月 G o 1.11 リ リ ー ス W asm サ ポ ー ト 2019年 W A SI 0.1 リ リ ー ス 2023年 8月 G o 1.21 リ リ ー ス W A SI 0.1 サ ポ ー ト 2024年 1月 W A SI 0.2 リ リ ー ス 2024年 8月 W A SI 0.2.1 リ リ ー ス W asm O C I A rtifact layout 2025年 W A SI 0.3 リ リ ー ス ? 2025年 2月 G o 1.24 リ リ ー ス W A SI 0.1 リ ア ク タ ー モ ジ ュ ー ル サ ポ ー ト
  10. ネットワーク 15 WASI 0.2の特徴 • コンポーネントモデルの採用 • ネットワーク対応 WASI -

    Wasmを汎用バイナリとして利用するためのAPI仕様 WASI 0.1 (=wasip1 - POSIX APIを参考に策定 / ネットワークは未サポート WASI 0.2 (=wasip2 - Wasmコンポーネントモデルをベースに再設計 2018年 8月 G o 1.11 リ リ ー ス W asm サ ポ ー ト 2019年 W A SI 0.1 リ リ ー ス 2023年 8月 G o 1.21 リ リ ー ス W A SI 0.1 サ ポ ー ト 2024年 1月 W A SI 0.2 リ リ ー ス 2024年 8月 W A SI 0.2.1 リ リ ー ス W asm O C I A rtifact layout 2025年 W A SI 0.3 リ リ ー ス ? 2025年 2月 G o 1.24 リ リ ー ス W A SI 0.1 リ ア ク タ ー モ ジ ュ ー ル サ ポ ー ト 標準パッケージを使えない →wasi:httpのWIT使ってインターフェースを実装する
  11. wasi:http/proxyを実装する 17 world proxy { import ...; export incoming-handler; }

    wasi:http/proxyの定義 WASI 0.2の2つのエントリーポイント • wasi:cli/command → CLIコマンドの起動 • wasi:http/proxy → HTTPサーバーの起動
  12. wasi:http/proxyを実装する 18 world http-proxy { include wasi:cli/[email protected]; include wasi:http/[email protected]; }

    wit/world.wit e.g.$ wkg wit build -o world.wasm wit/world.wit e.g.$ wit-bindgen-go generate \ > --world http-proxy \ > --out internal/gen world.wasm
  13. • wkg ◦ WITをWasmに変換 ◦ wit/world.wit → world.wasm • wit-bindgen-go

    ◦ WasmからGoのコードを生成 ◦ world.wasm → internal/gen wasi:http/proxyを実装する 19 e.g.$ wkg wit build -o world.wasm wit/world.wit e.g.$ wit-bindgen-go generate \ > --world http-proxy \ > --out internal/gen world.wasm
  14. wasi:http/proxyを実装する 20 e.g.$ wkg wit build -o world.wasm wit/world.wit e.g.$

    wit-bindgen-go generate \ > --world http-proxy \ > --out internal/gen world.wasm ./internal/gen/ ./wit/world.wit import ( gohttp "net/http" "github.com/a-skua/go-wasi/internal/gen/wasi/http/incoming-handler" "github.com/a-skua/go-wasi/internal/gen/wasi/http/types" ) var Handler gohttp.Handler func init() { incominghandler.Exports.Handle = handle } func handle(in types.IncomingRequest, out types.ResponseOutparam) { r, _ := http.ParseRequest(in) // TODO: err handle w := http.NewResponseWriter(out) defer w.Flush() Handler.ServeHTTP(w, r) } http.Handler func (w http.ResponseWriter, r *http.Request) error wasi:http/incoming-handler func(request: incoming-request, response-out: response-outparam) 生成されたコード
  15. wasi:http/proxyを実装する 21 package main import ( "fmt" "net/http" "github.com/a-skua/go-wasi/http/proxy" )

    func main() {} func init() { proxy.Handler = http.HandlerFunc(httpHandler) } func httpHandler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, 世界!\n") } e.g.$ wasmtime serve S cli http-proxy.wasm Serving HTTP on http://0.0.0.08080/ e.g.$ curl http://localhost:8080 Hello, 世界! e.g.$ tinygo build --target=wasip2 --no-debug \ > --wit-package world.wasm --wit-world proxy \ > -o proxy.wasm proxy.go
  16. • Pure Goで体験するWasmの未来 - Speaker Deck • Wasm OCI Artifact

    layout | CNCF TAG Runtime • GitHub - bytecodealliance/go-modules • GitHub - bytecodealliance/wasm-pkg-tools • Repository for design and specification of the Component Model リンク 26