SvelteKitをAWSでサーバーレスでSSRする方法
導入
SvelteKitアプリケーションをAWSにデプロイしたい!
そんな時に取れる選択肢はいくつかあります。
サーバーを常時稼働させるつもりであればEC2 + adapter-nodeの組み合わせで事足りるでしょう。
また、SPAであればAmplyfy + adpter-staticを使用すればサーバーレスで運用できます。
しかし、サーバーレスでSSRしたいとなると標準のadapterだけでは対応できません。
ここではコミュニティで作成された2つのadapterを紹介します。
なおいずれの方法もAWS-CDKを使用するため、マシンに事前にAWS CLIのセットアップとアクセス認証を済ませておく必要があります。
MikeBild/sveltekit-adapter-aws
AWS-CDKを用いてCloudfront,S3,API GateWay,Lambdaにリソースをデプロイします。
静的リソース(デフォルトでは/_app/*)はS3とCDNの組み合わせで高速に配信され、サーバー処理はLambdaが担います。
詳細な導入はREADMEを参照いただきたいのですが、手順は簡単です。
- 既存のSvelteKitプロジェクトに、adapterを下記のコマンドでインストールします。
npm i -D sveltekit-adapter-aws
-
sveltekit-adapter-aws
を使用するようにsvelte.config.js
を書き換えます。
+ import { adapter } from 'sveltekit-adapter-aws';
import preprocess from 'svelte-preprocess';
export default {
preprocess: preprocess(),
kit: {
+ adapter: adapter({
+ autoDeploy: true,
+ }),
},
};
-
npm run build
をすると自動的にデプロイが実行され、表示されたURLにアクセスするとページが表示されます。
…はずなのですが、試しに実行してみたところこんなエラーが出ました。
Resource handler returned message: "The runtime parameter of nodejs14.x is no longer supported for creating or updating AWS Lambda functions. We recommen
d you use the new runtime (nodejs20.x) while creating or updating functions. (Service: Lambda, Status Code: 400, Request ID: ...)" (RequestToken: ..., HandlerErrorCode: InvalidRequest)
以下のIssueでも言及されているようですが、古いバージョンのNodeを使用しているためエラーが発生する場合があるようです。
回避方法が分からなかったため、ここではもう一つのadapterを紹介しておきます。
jill64/sveltekit-adapter-aws
私が作成したadapterです。
こちらも詳細な導入はREADMEを参照ください。
まずは最小構成から解説します。
導入手順は1つ目のadapterとほぼ同じです。
- 既存のSvelteKitプロジェクトに、adapterを下記のコマンドでインストールします。
npm i -D @jill64/sveltekit-adapter-aws
-
@jill64/sveltekit-adapter-aws
を使用するようにsvelte.config.js
を書き換えます。
+ import adapter from '@jill64/sveltekit-adapter-aws';
import preprocess from 'svelte-preprocess';
export default {
preprocess: preprocess(),
kit: {
+ adapter: adapter({
+ deploy: true,
+ }),
},
};
-
npm run build
をすると自動的にデプロイが実行され、表示されたURLにアクセスするとページが表示されます。
加えてこのadapterは利用シチュエーションに合わせて4つの異なるアーキテクチャから選択できることが特徴です。順番に解説していきたいと思います。
1. lambda-mono
単一のLambdaに全てのアセットをアップロードして、全てのリクエストを処理します。
使用するにはadapterのconfigに以下を追加します。
adapter({
deploy: true,
+ architecture: 'lambda-mono'
})
オプションでCDNを前段に追加することができます。
追加するにはadapterのconfigに以下を追加するだけです。
adapter({
deploy: true,
architecture: 'lambda-mono'
+ cdn: true
})
高速なデプロイが可能なのでテストや開発用に適していますが、静的アセットの処理がLambdaを介するため遅くなってしまいます。
CDNを追加すれば多少マシになりますがプロダクションには向きません。
2. lambda-s3
前述したMikeBild/sveltekit-adapter-aws
に近いアーキテクチャです。
使用するにはadapterのconfigに以下を追加します。
adapter({
deploy: true,
+ architecture: 'lambda-s3'
})
またarchitecture
オプションを選択しない場合はこれがデフォルトになります。
MikeBild/sveltekit-adapter-aws
との違いはLambdaの関数URLを使用することです。
これによりAPI Gatewayが不要になっているほか、Lambdaのストリーミングレスポンスが使用可能になっています。
基本的なユースケースに対応できますが、SSGのアセットがLambdaから配信されるため250MBのサイズリミットがあることが唯一のデメリットとなります。
そのため、大規模なSSGを検討している場合は以降に紹介するアーキテクチャの採用が必要です。
3. edge-bundled
サーバー処理にLambda@Edgeを使用してエッジロケーションでサーバーを実行します。
使用するにはadapterのconfigに以下を追加します。
adapter({
deploy: true,
+ architecture: 'edge-bundled'
})
この場合、SSGのアセットはS3から配信されるため事実上無制限のSSGが可能です。
また、Lambda@Edgeを使用するため良好なTTFBが期待できます。
ただし、Lambda@Edgeのプラットフォームの制限からストリーミングレスポンスは使用できません。
また、実行環境もLambdaに比べて貧弱なので、このアーキテクチャはSSG主体のアプリケーションに向いている構成と言えるでしょう。
4. edge-unbundled
Lambda@EdgeとLambdaを併用してリクエストを処理します。
使用するにはadapterのconfigに以下を追加します。
adapter({
deploy: true,
+ architecture: 'edge-unbundled'
})
この場合も、SSGのアセットはS3から配信されるため事実上無制限のSSGが可能です。
またサーバー処理にはLambdaを使用するため、ストリーミングレスポンスの利用やサーバースペックの向上が可能です。
ただし、アーキテクチャが複雑になるためデバックが少し難しくなるほか、デプロイにも時間がかかります。
また、リクエストがLambda@Edgeを通ってからLambdaに転送されるためTTFBもわずかに悪化してしまいます。
大規模なSSGと重めのサーバー処理を両立させたい場合はこのアーキテクチャが適しているでしょう。
総括
いかがだったでしょうか。
この記事がAWSでSvelteKitを運用しようとしている方の助けになれば幸いです。
またjill64/sveltekit-adapter-aws
についてバグや不明点がありましたらぜひ以下からIssueを開いてください。
Discussion