🚢

React Router SPA+HonoをViteで開発しAWS Lambdaで公開する

に公開

npm create honoのcloudflare-workers+viteのAWS Lambda版相当を試したかったので作った。
aws-lambdaも見たが、こちらはviteなしのcloudflare-workers相当であるため、Vite開発機能がない他、CDK依存も外しているシンプルなサンプルであり、デプロイ時に別途リソースの準備が必要であり、求めるサンプルではなかった。

コードは以下にある。

https://github.com/ofk/example-react-router-hono-cdk

ローカル環境の構築

以前の記事で作った構成を流用した。なので、シンプルにadapterなしのhono-react-router-adapterをviteで使う構成である。これはLambda独自の機能を使うことは少ないという判断でこうした。が、これは本格利用した場合、やはりLambdaEventLambdaContextが模倣されるAWS Lambda用のadapterが必要となるかもしれない。

デプロイ先の構成

SPA+API構成なので、今後色々なスタックを積むことが予想される。なので、全てをLambdaに詰め込んだりせずに、CloudFrontからS3バケットに繋げSPAを配信し、/apiパスのみAPI Gatewayを経由しLambdaに流す構成とした。このスタックを手で作成するのはやりたくないので、CDKで実装した。

CDKの依存パッケージをSPAのものとは混ぜたくなく、またSPAのLinterやFormatterその他の影響を避けるため、SPAのルートをappディレクトリに、CDKのルートをinfraディレクトリに分ける構成とした。

Lambdaへのデプロイ

default exportをするserver/index.tsを読み込み、handleをexportすることで対応した。

server-lambda.ts
import { handle } from 'hono/aws-lambda';

import app from './server';

export const handler = handle(app);

このような形で、Vite開発とAWS Lambdaデプロイを両立している。

ドキュメントのAWS LambdaのデプロイではNodejsFunctionを使っているがこれは採用しなかった。Dockerダウンロードが始まり非常に低速だったためだ。また、SPAをビルドする都合、appディレクトリのビルド環境は整備されるため、SPAビルドのタイミングでサーバーをesbuildするようにした。

CDKのコードはほぼChatGPTに記述させたのでベストプラクティスから外れているコードが含まれているかもしれない。

https://github.com/ofk/example-react-router-hono-cdk/blob/main/infra/lib/app-stack.ts

あとがき

Honoの抽象化は非常に良かった。adapterは使い勝手をよくする余地がありそうで、本格的に利用することになれば、何かフィードバックができると良い。
それとは別にCDKが非常に遅く体験が悪かった。デプロイにおおよそ10分かかる。これは設定を変えたら3分程度に縮まるという話を見かけたので、実用する場合は以下を参考に修正を試みる。

https://zenn.dev/marumarumeruru/articles/66917efe5ef7c6

IaCを変えると速くなるというのはありそうだが、今回はこのくらいでこれ以上は追求しない。

Discussion