[アップデート]Cloudflare WorkersでNode.jsのAsyncLocalStorage、EventEmitter、Buffer、assert、およびutilの一部が動作可能になりました!

[アップデート]Cloudflare WorkersでNode.jsのAsyncLocalStorage、EventEmitter、Buffer、assert、およびutilの一部が動作可能になりました!

Clock Icon2023.03.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

どうも、AWS事業本部オペレーション部の西村祐二です。

最近、Cloudflareに注目しており、今日、以下のようなブログが公開されました。

Node.js compatibility for Cloudflare Workers – starting with Async Context Tracking, EventEmitter, Buffer, assert, and util

Cloudflare Workersは、ServiceWorkerのAPIがCDNエッジ上で動作するコンピューティングリソースであるため(間違っていたら指摘してください)、Node.js APIが使用されるライブラリなどを利用する場合は、polyfillを利用してバンドルしてデプロイする必要がありました。

しかしながら、Cloudflare Workersには多くの制限があり、複雑なことは現状では難しいとされています。

Limits · Cloudflare Workers docs

しかし、今回のアップデートによりAsyncLocalStorage、EventEmitter、Buffer、assert、そしてutilの一部のNode.js APIはバンドルせずにCloudflare Workers上で利用できるようになりました。

どうやってNode.jsのAPIを利用できるようにするか

wrangler.tomlに下記フラグを設定することでNode.jsのAPIが利用できるようになります。

compatibility_flags = [ "nodejs_compat" ]

試してみた

Workersを作成

wranglerを使ってmy-workerというWorkersを作成していきます。

※wranglerのバージョンは2.13.0

$ wrangler init my-worker -y
$ cd my-worker

wrangler.tomlを編集

wrangler.tomlにNode.jsを有効化するためのフラグを追加します。

name = "my-worker"
main = "src/index.ts"
compatibility_date = "2023-03-24"
compatibility_flags = [ "nodejs_compat" ]

BufferのAPIを試してみる

今回は簡単に試せそうなBufferを使って対応したNode.jsのAPIが動作するか確認していきます。

最初に生成されたsrc/index.tsにブログに記載されていたサンプルコードを貼り付けます。

import時にはnode:を付ける必要があるようです。

import { Buffer } from 'node:buffer';

const buf = Buffer.from('hello world', 'utf8');
console.log(buf.toString('hex'));
// Prints: 68656c6c6f20776f726c64
console.log(buf.toString('base64'));
// Prints: aGVsbG8gd29ybGQ=

export interface Env {
	// Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/
	// MY_KV_NAMESPACE: KVNamespace;
	//
	// Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime-apis/durable-objects/
	// MY_DURABLE_OBJECT: DurableObjectNamespace;
	//
	// Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/
	// MY_BUCKET: R2Bucket;
	//
	// Example binding to a Service. Learn more at https://developers.cloudflare.com/workers/runtime-apis/service-bindings/
	// MY_SERVICE: Fetcher;
}

export default {
	async fetch(
		request: Request,
		env: Env,
		ctx: ExecutionContext
		): Promise<Response> {
			return new Response("Hello World!");
		},
};

ローカルで動作確認

wranglerを使ってローカルで動作確認できるか試してみます

$ npm start


> [email protected] start
> wrangler dev

 ⛅️ wrangler 2.13.0
--------------------
⬣ Listening at http://0.0.0.0:8787
- http://127.0.0.1:8787
- http://xxx.xxx.xxx.xxx:8787
Total Upload: 0.49 KiB / gzip: 0.30 KiB
68656c6c6f20776f726c64
aGVsbG8gd29ybGQ=
╭──────────────────────────────────────────────────────────────────────────╮
│ [b open a      [d open        [l turn on local   clear      [x to     │
│   browser,       Devtools,      mode,              console,      exit    │
╰──────────────────────────────────────────────────────────────────────────╯

問題なく動作していそうですね。

ローカルで簡単に動作確認できるのはとても嬉しいですね。

Workersにデプロイ

デプロイする前に export default外のconsole.logだとログ出力されなかったので、中でconsole.logを記載するように修正します。


...snip
export default {
	async fetch(
		request: Request,
		env: Env,
		ctx: ExecutionContext
		): Promise<Response> {
			console.log(buf.toString('hex'));
			// Prints: 68656c6c6f20776f726c64
			console.log(buf.toString('base64'));
			// Prints: aGVsbG8gd29ybGQ=
			return new Response("Hello World!");
		},
};

下記コマンドでデプロイします。

$ npm run deploy

> [email protected] deploy
> wrangler publish

 ⛅️ wrangler 2.13.0
--------------------
Total Upload: 0.53 KiB / gzip: 0.30 KiB
Uploaded my-worker (1.56 sec)
Published my-worker (0.28 sec)
  https://xxxxxxxxxxxxx.workers.dev
Current Deployment ID: xxxxxxx-xxxxxxx-xxxxxxx-xxxxxxx-xxxxxxx

ログ確認するためにtailコマンドを打っておきます。

$ wrangler tail --format=pretty

払い出されたURLにアクセスすると下記のようなログが流れてきました。

問題なくNode.jsのBufferが動作してそうですね。

--------------------
Successfully created tail, expires at 2023-03-24T13:43:42Z
Connected to my-worker, waiting for logs...
GET https://xxxxxxx.workers.dev/ - Ok @ 2023/3/24 16:50:15
  (log) 68656c6c6f20776f726c64
  (log) aGVsbG8gd29ybGQ=
GET https://xxxxxxx.workers.dev/favicon.ico - Ok @ 2023/3/24 16:50:16
  (log) 68656c6c6f20776f726c64
  (log) aGVsbG8gd29ybGQ=

さいごに

簡単ではありますが、対応されたNode.jsのAPIをCloudflare Workers上で試してみました。

コンフィグに一行設定を追加するだけで、とても簡単にNode.jsのAPIを利用することができました。

あと、公開されたブログの最後のほうに

"We currently have implementations of the string decoder, streams and crypto APIs in active development."

以下、機械翻訳

"現在、文字列デコーダ、ストリーム、および暗号化 API の実装が活発に開発してます。"

と記載があって今後のアップデートもとても楽しみです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.