🔥

Hono DocsのGetting StartにApp Engineがないの なぁぜなぁぜ?

2024/12/22に公開

この記事はHono Advent Calendar 2024 22日目の記事です。

表題の答えは記事の最後で。

なぜこのテーマなのか?

突然ですが、僕はTypeScriptとGoogle Cloudがめっちゃ好きです。もちろんTypeScriptでめちゃくちゃいい感じに使えるHonoも好きです。

なんですが公式ドキュメントのGetting Startを見ると…

Cloudflare、もちろんある!

AWS Lambda、ある!

Azure Functions、ある!

Google Cloudのサービス、、、、ない!!!!!!!!!!!!!!!!

VercelDenoまであるのにGoogle Cloudのサービスだけが一つもない。悲しい。。。

と思ったので、この記事ではHonoをApp Engineで動かしながら、HonoのDocsのGetting StartにApp Engineを追加するPRを出してみた話をします。

Honoを準備

まずは素のHonoを用意していきます。

% npm create hono@latest hono_appengine
Need to install the following packages:
create-hono@0.14.3
Ok to proceed? (y) y
create-hono version 0.14.3
✔ Using target directory … hono_appengine
? Which template do you want to use?
  lambda-edge
  netlify
  nextjs
❯ nodejs
  vercel
  x-basic
  aws-lambda

爆速で動くサンプルが出来上がる。このスピード感こそHono。

import { serve } from '@hono/node-server'
import { Hono } from 'hono'

const app = new Hono()

app.get('/', (c) => {
  return c.text('Hello Hono!')
})

const port = 3000
console.log(`Server is running on http://localhost:${port}`)

serve({
  fetch: app.fetch,
  port
})

npm run devで動作確認する。

ここまではあっさり。

App Engineで動かすための準備をする

ビルドの準備

App Engineスタンダード環境のNode.jsでHonoを動かすために、package.jsonbuildコマンドとstartコマンドを追加します。

これはjsにビルドした状態でNodeランタイムに載せる必要があるのと、App Engineがアプリケーションの起動にstartというコマンドを叩くためです。

json
    "scripts": {
        "dev": "tsx watch src/index.ts",
+        "app-engine-build": "tsc --build",
+        "start": "node dist/index.js"
    },

tsconfig.jsonにビルド先を指定する。

tsconfig.json
{
  "compilerOptions": {
    "target": "ESNext",
    "module": "NodeNext",
    "strict": true,
    "verbatimModuleSyntax": true,
    "skipLibCheck": true,
    "types": [
      "node"
    ],
    "jsx": "react-jsx",
    "jsxImportSource": "hono/jsx",
+    "outDir": "./dist",
  }
}

portの準備

App EngineではApp Engine側のポートでアプリケーションが動く。App Engineの稼働ポートはprocess.env.PORTで取得できるため、ソース側も修正しておきます。

index.ts
import { serve } from "@hono/node-server";
import { Hono } from "hono";

const app = new Hono();

app.get("/", (c) => {
    return c.text("Hello Hono!");
});

-const port = 3000;
+const port = Number(process.env.PORT) || 3000;
console.log(`Server is running on http://localhost:${port}`);

serve({
    fetch: app.fetch,
    port,
});

.gcloudignoreの用意

ビルドしたjsファイルだけをAppEngineにおけばいいので、srcファイルは不要です。よって、対象外にしておきます。

# This file specifies files that are *not* uploaded to Google Cloud
# using gcloud. It follows the same syntax as .gitignore, with the addition of
# "#!include" directives (which insert the entries of the given .gitignore-style
# file at that point).
#
# For more information, run:
#   $ gcloud topic gcloudignore
#
.gcloudignore
# If you would like to upload your .git directory, .gitignore file or files
# from your .gitignore file, remove the corresponding line
# below:
.git
.gitignore

# Node.js dependencies:
node_modules/
src/

App Engineへデプロイ

app.yamlを作成。

runtime: nodejs20

Cloud Consoleからプロジェクトを作成し、プロジェクトIDを取得。

以下から、App Engine APIを有効にしておく必要があります。

https://cloud.google.com/build/docs/deploying-builds/deploy-appengine?hl=ja

その後ビルドし、

npm run app-engine-build
gcloud app deploy --project [プロジェクトID]

LGTM!!

なぜHonoのGetting StartにAppEngineがないのか?

以上の一連のAppEngineにデプロイまでの流れを整理してPRを出してみました。

https://github.com/honojs/website/pull/546

さっそく@yusukebeさんからこういうコメントが。

The reason we didn't add Google App Engine to the list is that anyone who wants to use it can just look at Node.js. AWS Lambda and Lambda@Edge do not use Node.js, and they are specific platforms, so we need to put them on our website. For GAE, I don't think we need this PR because users just do it the Node.js way.

要約するとGAEはNode.jsランタイムなんだから、既にあるNode.jsのドキュメント見ればいいよねということでした。ごもっとも…

ということでPRはそっ閉じして、この記事だけ世に残しておくことにします。

おわり

次こそはなにかコントリビュートしたいなぁ。。。ドキュメントじゃなくて機能的な何かで。

npm create hono@latestのオプションにgcp-appengineを追加してAppEngineで動かすために必要な設定とかの雛形を用意できるようにするとかなら需要あるのかな🤔

チラッとみてる感じだと、startercreate-honoをいじってあげれば良さそうな気がしていますが…

ってか別に本体にコントリビュートせずとも自分がほしいと思ってるなら作ればいいやと思ってしまったのでどっちにしてもやってみるか。

とりあえず勢いでアドカレに参加してネタに困ってたけど無事に(?)記事としては成立した(と思う)のでよかった!

Discussion