6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS AmplifyでSvelteKitアプリケーションをデプロイする

Last updated at Posted at 2024-09-21

はじめに

  • AWS Amplifyはあまり触ってこなかったけど、Gen2で色々いい感じになったらしい
  • 推しフレームワークSvelteKitをGen2で動かして使用感を試してみる

SvelteKitとわたし

  • SvelteKitは、WebフロントエンドフレームワークSvelteをベースとしたフルスタックアプリケーションのためのフレームワークです
  • 筆者はSvelteKitを、Cloudflare Pages、AWS Lambda、AWS Lambda + Web Adapterでそれぞれ運用していて、それぞれのうれしみ・つらみがなんとなくわかってきたところです

AmplifyにSvelteKitをデプロイする

公式ドキュメントがあり、amplify-adapterを利用すると良さそうです。ただし、

SvelteKitは「Adapter」という仕組みを利用して、同一コードから複数の環境へデプロイすることを可能としています。オフィシャルにメンテナンスされているアダプターのほか、サードパーティによるアダプターもあります。amplify-adapterは後者です。

手順

上記ページのとおりで良く、要約すると以下です。

  1. SvelteKitアプリケーションを作成する
  2. amplify-adapterをインストールし、デフォルトと差し替える
  3. ソースコードをGitHubへアップロードする
  4. AWS Amplifyコンソールでプロジェクトを作成する
  5. 3のリポジトリを選択する
  6. ビルド設定で、ビルド先ディレクトリとしてbuildを指定する
# コマンド例
npm create svelte@latest sveltekit-amplify
npm install -D amplify-adapter
# svelte.config.jsを修正
git init
git add .
git commit -m init
git push origin sample-repo
# 以降はAWS Amplifyコンソールでの操作

上記ページでは

In the amplify.yml file, locate the frontend build commands section. Enter - cd build/compute/default/ and - npm i --production.

と説明されています。しかしデフォルトの状態ではbuild/compute/default/package.jsondependenciesが記述されているわけでもないので、この設定をせずとも動作しました。ビルド時にminify出来ない依存関係が含まれている場合は、この設定が必要となります(例:バイナリを含むライブラリなど)。

ここまででAmplifyによりSvelteKitアプリケーションがデプロイされ、正常に動作するはずです。

Screenshot 2024-09-21 at 11.30.57.png

デプロイプレビュー

Screenshot 2024-09-21 at 12.21.04.png

  • プライベートリポジトリであり、かつPR先リポジトリのプレビューが、コンソール上で有効化されていれば、PR作成時にビルドが走り、プレビューページのURLを取得できる

API routes

src/routes/api/hello/+server.ts
import type { RequestHandler } from '@sveltejs/kit';

const getHandler: RequestHandler = async (request) => {
    return new Response('Hello from the server!');
};

const postHandler: RequestHandler = async (request) => {
    return new Response('Hello from the server! post');
};

export const GET = getHandler;
export const POST = postHandler;

SvelteKitのお作法でAPIエンドポイントを実装しておく

curl https://path/to/app/api/hello
Hello from the server!

curl -X POST https://path/to/app/api/hello
Hello from the server! post

問題なく動作する。

SSRとStreamingをテストする

SvelteKitはStreaming、ベースのHTMLを先にレスポンスし、動的コンテンツはサーバー内の読み込みが完了した段階で後から送るという機能に対応しています。+page.server.tsでデータフェッチングを記述することでSSRを実装することができます。今回は下記のコードを利用してみます。

+page.server.ts
import type { PageServerLoad } from './$types';

type Todo = {
    userId: number;
    id: number;
    title: string;
    completed: boolean;
};

export const load: PageServerLoad<{
    todos: Promise<Todo[]>;
}> = async ({ fetch }) => {
    // fetch sample data
    return {
        todos: new Promise<Todo[]>((resolve) => {
            setTimeout(() => {
                fetch('https://jsonplaceholder.typicode.com/todos')
                    .then((response) => response.json())
                    .then((todos) => {
                        resolve(todos);
                    });
            }, 2000);
        }),
    };
};
+page.svelte
<script lang="ts">
    import type { PageServerData } from './$types';

    export let data: PageServerData;
</script>

<main>
    <div>
        {#await data.todos}
            loading...
        {:then todos}
            <ul>
                {#each todos as todo}
                    <li>{todo.title}</li>
                {/each}
            </ul>
        {/await}
    </div>
</main>

このrouteは下記の順序で処理されるよう、記述されています。

  1. loading...が表示される
  2. サーバー側は、2秒待機->fetch()->json()を実行した結果を返すPromiseload()で返す
  3. コンポーネント側は、#awaitブロックにより、Promiseが解決したタイミングで表示を切り替える(=2秒程度待ったらTODOリストが表示される)

Screenshot 2024-09-21 at 11.48.07.png
Promiseの解決前

Screenshot 2024-09-21 at 11.48.19.png
解決後

この実装で、開発サーバーではストリーミングが動作しますが、結果としてはAmplify環境では動作しませんでした。エラーが出るとかではなく、ストリーミングしたい要素まで全てが読み込まれた状態で初めてページがレスポンスされる挙動となります(なのでSSR自体は動作している)。

Amplifyにストリーミングレスポンスを有効化するようなオプションはなく、下記の記事でも言及されているように、現状でストリーミングレスポンスは非対応のようです。SSR Streamingはパフォーマンス上、たいへん有用ですので対応が待たれます。

使用感

Cloudflare Pagesとの比較

  • 同じくらいの手軽さでSSRできるSvelteKitをデプロイできる
  • Pagesはアーティファクトサイズ制限がかなり厳しい・ランタイムが薄く利用出来ないAPIがあるので、その点でかなり優位
  • AmplifyはもちろんエッジSSRではないことは割り引いて見る必要がある
  • ビルドは遅い(Amplifyが)

AWS Lambdaとの比較

  • LambdaでSvelteKitをデプロイするには、同じくサードパーティのアダプターが必要(jill64/sveltekit-adapter-aws
      • 静的アセットはS3から・それ以外はLambdaから返すなど、いくつかのアーキテクチャパターンを選択できる
    • 自動でCDKをジェネレートするような作り
  • Amplifyが利用出来るならこの手段を取る必要はないかもしれない
  • ただしLambdaはストリーミングレスポンスをサポートしている

AWS Lambda(+ Lambda Web Adapter)との比較

  • ローカルでもコンテナ開発が前提なら、Web Adapter利用のパターンの方がポータブルなコードを書けるので、Amplifyよりも便利かもしれない
  • そこそこ厚いランタイムの上でSSRしたいけど、そのためだけにコンテナを利用するのはどうみても過剰、みたいなケースでAmplifyを利用すると幸せになれそう
  • 静的ファイルまでもがLambdaを通じて配信される単には留意

まとめ

  • SvelteKitもAmplifyでお手軽にデプロイできる
  • SSRも当然に動作するがストリーミングは未対応
  • AmplifyはAWSサービスとの統合にも強みがあるはず(別途検証)
6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?