7日目: Cloudflare Workers を探訪

名前は聞いたことあるけど、ずっと触っていなかった Cloudflare Workers を探訪。 以下のチュートリアル記事がよさそうだったので、それをやってみる。

zenn.dev

コマンド一発で Hello World アプリケーションの雛形ができた。

$ npm create cloudflare@latest

Need to install the following packages:
  create-cloudflare@2.7.1
Ok to proceed? (y) y

using create-cloudflare version 2.7.1

╭ Create an application with Cloudflare Step 1 of 3
│
├ In which directory do you want to create your application?
│ dir ./hello
│
├ What type of application do you want to create?
│ type "Hello World" Worker
│
├ Do you want to use TypeScript?
│ yes typescript
│
├ Copying files from "hello-world" template
│
├ Retrieving current workerd compatibility date
│ compatibility date 2023-11-21
│
├ Do you want to use git for version control?
│ yes git
│
╰ Application created

╭ Installing dependencies Step 2 of 3
│
├ Installing dependencies
│ installed via `npm install`
│
├ Committing new files
│ git commit
│
╰ Dependencies Installed

╭ Deploy with Cloudflare Step 3 of 3
│
├ Do you want to deploy your application?
│ yes deploy via `npm run deploy`
│
├ Logging into Cloudflare checking authentication status
│ logged in
│
├ Selecting Cloudflare account retrieving accounts
│ account **********@**********.com's Account
│
├ Deploying your application
│
> hello@0.0.0 deploy
> wrangler deploy

 ⛅️ wrangler 3.17.1
-------------------
Total Upload: 0.19 KiB / gzip: 0.16 KiB
▲ [WARNING] You need to register a workers.dev subdomain before publishing to workers.dev


? Would you like to register a workers.dev subdomain now?
🤖 Using default value in non-interactive context: yes

✘ [ERROR] This command cannot be run in a non-interactive context


If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose
🪵  Logs were written to "/path/to/.config/.wrangler/logs/wrangler-2023-11-29_09-43-24_472.log"

│
Error:
> hello@0.0.0 deploy
> wrangler deploy

 ⛅️ wrangler 3.17.1
-------------------
Total Upload: 0.19 KiB / gzip: 0.16 KiB
▲ [WARNING] You need to register a workers.dev subdomain before publishing to workers.dev


? Would you like to register a workers.dev subdomain now?
🤖 Using default value in non-interactive context: yes

✘ [ERROR] This command cannot be run in a non-interactive context


If you think this is a bug then please create an issue at https://github.com/cloudflare/workers-sdk/issues/new/choose
🪵  Logs were written to "/path/to/.config/.wrangler/logs/wrangler-2023-11-29_09-43-24_472.log"

npm ERR! code 1
npm ERR! path /path/to/username
npm ERR! command failed
npm ERR! command sh -c create-cloudflare

npm ERR! A complete log of this run can be found in:
npm ERR!     /path/to/.npm/_logs/2023-11-29T09_42_51_999Z-debug-0.log

とはいえなんかエラーがでた...。なんだろう??

$ cd hello

ディレクトリに移動して、 npm run deploy してみる。

$ npm run deploy

> hello@0.0.0 deploy
> wrangler deploy

 ⛅️ wrangler 3.17.1
-------------------
✔ Would you like to help improve Wrangler by sending usage metrics to Cloudflare? … yes
Your choice has been saved in the following file: ../../../../.config/.wrangler/metrics.json.

  You can override the user level setting for a project in `wrangler.toml`:

   - to disable sending metrics for a project: `send_metrics = false`
   - to enable sending metrics for a project: `send_metrics = true`
Total Upload: 0.19 KiB / gzip: 0.16 KiB
▲ [WARNING] You need to register a workers.dev subdomain before publishing to workers.dev


✔ Would you like to register a workers.dev subdomain now? … yes
✔ What would you like your workers.dev subdomain to be? It will be accessible at https://<subdomain>.workers.dev … furikake555
✔ Creating a workers.dev subdomain for your account at https://furikake555.workers.dev. Ok to proceed? … yes

Success! It may take a few minutes for DNS records to update.
Visit https://dash.cloudflare.com/e772fd4854ea799ab6fa582996e4fa34/workers/subdomain to edit your workers.dev subdomain
Uploaded hello (0.68 sec)
Published hello (28.54 sec)
  https://hello.furikake555.workers.dev
Current Deployment ID: 1bd249e1-f5bd-4787-9a54-8b4f7c2e9a99

(2-3分待ったら)デプロイが完了したっぽい。

$ curl https://hello.furikake555.workers.dev
Hello World!

ちゃんと動いている最高。 src/index.ts を覗いてみる。

/**
 * Welcome to Cloudflare Workers! This is your first worker.
 *
 * - Run `npm run dev` in your terminal to start a development server
 * - Open a browser tab at http://localhost:8787/ to see your worker in action
 * - Run `npm run deploy` to publish your worker
 *
 * Learn more at https://developers.cloudflare.com/workers/
 */

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;
    //
    // Example binding to a Queue. Learn more at https://developers.cloudflare.com/queues/javascript-apis/
    // MY_QUEUE: Queue;
}

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

npm run dev でローカルサーバーが立ち上がるようだ。

$ curl http://0.0.0.0:8787
Hello World!

同じ結果!適当に更新して再度リクエストを送ってみる。

diff --git a/src/index.ts b/src/index.ts
index 8087b85..21d2585 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -27,6 +27,6 @@ export interface Env {

 export default {
        async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
-               return new Response('Hello World!');
+               return new Response('わっしょいわっしょい');
        },
 };
$ curl http://0.0.0.0:8787
わっしょいわっしょい

すぐに反映された。とりあえず紹介したサンプル同様におみくじを実装してみる。

const omikuji = ['大吉', '中吉', '小吉', '吉', '凶', '大凶'];

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    const i = Math.floor(Math.random() * omikuji.length);
    return new Response(omikuji[i], { headers: { 'content-type': 'text/plain; charset=UTF-8' } });
  },
};
$ curl http://0.0.0.0:8787
大凶

ヨシ!大凶!コミット積んでデプロイしてみる。

$ npm run deploy
$ curl https://hello.furikake555.workers.dev
中吉

すぐ反映された。かなり便利。CPUの実行時間など制限はあるようだけど、無料でも使えるので、明日以降もいろいろ触ってみる予定。

静的サイトのホスティングとかよさそう。