Svelte+SvelteKit(v1.0.0-next.151) メモ
prerender
全体を事前レンダリング
@sveltejs/adapter-static
というアダプターを使えば可能
ドキュメントルートのbuild
ディレクトリに結果が出力される
つまりは、すべてのページが事前にレンダリングされる SSG なサイトとなる
ページごとに事前レンダリング
ページコンポーネントの内で以下を指定すると、そのページのみ事前レンダリングし、静的な HTML を生成する
<script context="module" lang="ts">
export const prerender = true
</script>
しかし、上記を指定してビルドしても、そのページの HTML がどこにも出力されなかった。。(今度調べる)
@sveltejs/adapter-static
を使っていれば、この設定は不要
この機能を利用することで、全体的には SSR で HTML を生成するが、特定ページは事前レンダリングした HTML を使うみたいなことが実現できる
<script>
と<script context="module">
-
<script>
内で export が付いたフィールドは、親から props 経由で値を受け取れるフィールドとなる -
<script context="module">
内の export は関数などを export して他のモジュールで import して使える(いつものモジュール構文) - また、
export default
はコンポーネント自体を export するのに使われているため、script タグ内で利用できない
load
コンポーネントから load 関数を export しておくと、load 関数内の処理をそのコンポーネントが生成される前に実行してくれる
また、load 関数から props オブジェクトを return すると、それをコンポーネント側で受け取って利用できる
Next.js のgetStaticProps
(SSG)やgetServerSideProps
(SSR)に近い機能とのこと
ただし、これらの関数はビルド時やサーバーサイドのみで実行されるが、load 関数はこれに加えてクライアント側でページが更新された際も実行される
まとめると、load 関数は SSG や SSR の時も実行されるし、クライアント側のルーティングでページ更新した際も実行される
初期表示時などサーバーサイド側で load 関数がすでに実行されていると、クライアント側では実行されない
実行タイミングはいずれもコンポーネントが生成される前
注意点
- fetch は Web 標準の方の fetch ではなく、SvelteKit が提供する fetch でないといけない
- window や document などの環境特有の API を使うべきではない
- Node.js など違う環境で参照できないから
- load 関数は、クライアント側で動くのでセキュアな情報を fetch リクエストに含めない
以下は実装例
<script context="module" lang="ts">
import type { LoadInput } from '@sveltejs/kit'
export async function load({ fetch }: LoadInput) {
const res = await fetch('/api')
// propsをreturn
return res.ok
? {
props: {
results: await res.json().then(r => r.results)
}
}
: {
status: res.status,
error: new Error(`Error: /api fetch error`)
}
}
</script>
<script lang="ts">
export let results // これで受け取れる
</script>
$service-worker
Service Worker のみが使えるモジュール
以下のメンバーを持つ
- build
- バンドラー(Vite)で生成されたファイルの URL の文字列配列
- files
- static ディレクトリ内のファイルの URL の文字列配列
- timestamp
- ビルド時に
Date.now()
した結果
- ビルド時に
Service Worker は本番ビルドでのみ機能するが、svelte-kit preview
を使えばローカルでも確認できる
Service Worker でキャッシュ操作する流れ
- Service Worker をインストール
- 新しいキャッシュを作成(
CacheStorage.open
) - キャッシュのアセットを追加(
Cache.addAll
) - 処理完了後、SW を active 状態へ移行(
skipWaiting
)
- 新しいキャッシュを作成(
- Service Worker がアクティブ状態での処理
- 古いキャッシュを削除(
CacheStorage.delete
) - 処理完了後、クライアント(ブラウザ)をコントロールする(
ServiceWorkerGlobalScope.clients.claim
)- これにより SW がクライアントのコントローラーとして動き、fetch イベントなどが SW を通過するようになる
- これをやらないとリロード時まで SW がクライアントをコントロールできない
- 古いキャッシュを削除(
- fetch イベントの処理
- リクエストに一致するキャッシュがある
- キャッシュを取得して返す(
CacheStorage.match
)
- キャッシュを取得して返す(
- リクエストに一致するキャッシュがない
- リクエストを fetch する
- レスポンスをキャッシュを設定する(
Cache.put
) - レスポンスを返す
- リクエストに一致するキャッシュがある