+++ date = "2022-08-02" tags = ["zig","cloudflare"] title = "zigをwasmにしてcloudflareにdeployする" slug = "zig-wasm-cloudflare" +++ `zig`はprogramming-langの一つです。rustに似ていますが、c++寄りだと思います。 zigの利点はなんといってもwasmへのbuildの手軽さだと思います。 wasmはwebから実行できるbinaryです。 今後、webなどでもzigが採用されるケースが増えてくるかもしれません。 ```sh $ brew install zig $ mkdir zig-first-project $ cd zig-first-project $ zig init-exe $ cat src/main.zig $ cat build.zig $ zig build $ ./zig-out/bin/zig-first-project ``` hello-worldしてみます。 ```zig:src/main.zig const std = @import("std"); pub fn main() anyerror!void { const stdout = std.io.getStdOut().writer(); try stdout.print("hello, world!\n", .{}); } ``` ここまでで[ziglang/zig.vim](https://github.com/ziglang/zig.vim)を入れておいたほうがいいでしょう。zigはコード内にある`\t`の扱いが特殊です。 ```vim Plug 'ziglang/zig.vim' ``` 以下はcloudflare [blog](https://blog.cloudflare.com/running-zig-with-wasi-on-cloudflare-workers/)にあるexampleです。 ```zig:src/main.zig const std = @import("std"); pub fn main() anyerror!void { // setup allocator var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer std.debug.assert(!gpa.deinit()); const allocator = gpa.allocator(); // setup streams const stdout = std.io.getStdOut().writer(); const in = std.io.getStdIn(); var reader = std.io.bufferedReader(in.reader()).reader(); var counter: u32 = 1; // read input line by line while (try reader.readUntilDelimiterOrEofAlloc(allocator, '\n', std.math.maxInt(usize))) |line| { defer allocator.free(line); try stdout.print("{d}\t{s}\n", .{counter, line}); counter = counter + 1; } } ``` 単純に文字を渡すと行番号を追加して返します。 > just read some text from stdin and print it to stdout with line numbers, like running cat -n. But it does show just how easy the Workers paradigm is. This Zig program works identically on the command-line on my laptop and as an HTTP API deployed on Cloudflare Workers. ```zig:build.zig const std = @import("std"); pub fn build(b: *std.build.Builder) void { const target = b.standardTargetOptions(.{}); const mode = b.standardReleaseOptions(); const exe = b.addExecutable("zig-first-project", "src/main.zig"); exe.setTarget(target); exe.setBuildMode(mode); exe.install(); } ``` cloudflare workersではwasiがsupportされています。wasm-build, workers-deployまでをやってみます。 ```sh $ zig build -Dtarget=wasm32-wasi $ ls zig-out/bin/*.wasm $ echo "Hello\nWorld" | wasmtime ./zig-out/bin/zig-first-project.wasm 1 Hello 2 World $ npx wrangler@wasm login $ npx wrangler@wasm publish --name print-with-line-numbers --compatibility-date=2022-07-07 ./zig-out/bin/zig-first-project.wasm ``` これでdeployは完了です。取得されたworkersのaddressに文字列をpostしてみましょう。wasm-binaryが実行され、反応を返します。 ```sh $ echo "hello\nworld" | curl https://print-with-line-numbers.$USER.workers.dev -X POST --data-binary @- 1 hello 2 world ``` このようにめちゃくちゃ便利なcloudflare workersですが、cloudflareが提供する`workers.dev`のidは開発者なら取っておいたほうがよさそうです。