SvelteKit

Svelteベースのフルスタックフレームワーク。SSGモードも提供し、17k超のGitHubスターを誇る軽量高速フレームワーク。

言語:JavaScript/TypeScript
フレームワーク:Svelte
ビルド速度:Fast
GitHub Stars:17k
初回リリース:2020
人気ランキング:第10位

トレンド・動向

Svelteの軽量性とパフォーマンスを活かしたSSGとして注目。コンパイル時最適化により高速サイトを生成。

# 静的サイトジェネレータ SvelteKit ## 概要 SvelteKitは、Svelteベースのフルスタックフレームワークで、強力なSSG機能も提供します。17k超のGitHubスターを誇る軽量高速フレームワークで、Svelteの軽量性とパフォーマンスを活かしたSSGとして注目されています。コンパイル時最適化により高速サイトを生成します。 ## 詳細 SvelteKitは2020年から開発が始まった次世代フレームワークで、従来のJavaScriptフレームワークとは異なるアプローチを採用しています。Svelteのコンパイル時最適化により、ランタイムでのオーバーヘッドを最小限に抑え、極めて高速なサイトを生成できます。 ### 主要機能 #### 1. 柔軟なレンダリングモード - **静的生成(SSG)**: `adapter-static`を使用してビルド時に全ページを事前レンダリング - **サーバーサイドレンダリング(SSR)**: 動的なサーバーレンダリング - **シングルページアプリケーション(SPA)**: クライアントサイドのみのレンダリング - **プリレンダリング**: 選択的なページ事前レンダリング #### 2. Svelte駆動の軽量設計 - **コンパイル時最適化**: ビルド時にフレームワークコードを除去 - **ゼロランタイム**: 最小限のJavaScriptバンドル - **ファイルベースルーティング**: 直感的なディレクトリベースルーティング - **TypeScript統合**: ファーストクラスのTypeScriptサポート #### 3. パフォーマンス重視の設計 - **高速ビルド**: 効率的なビルドプロセス - **最小バンドルサイズ**: 不要なコードの自動除去 - **プリロード戦略**: インテリジェントなコードプリロード - **SEO最適化**: 組み込みのメタタグとSEOサポート #### 4. 開発者体験 - **ホットリロード**: 高速な開発環境での変更反映 - **型安全性**: 自動生成された型定義 - **エラーハンドリング**: 分かりやすいエラーメッセージ - **デバッグツール**: 統合されたデバッグ機能 ## メリット・デメリット ### メリット - **軽量性**: Svelteの特性により極めて軽量なバンドルサイズ - **高速パフォーマンス**: コンパイル時最適化による高いランタイム性能 - **学習コストの低さ**: シンプルな構文とファイルベースルーティング - **柔軟性**: 複数のレンダリングモードとアダプターサポート - **TypeScript統合**: 優秀なTypeScript開発体験 - **SEOフレンドリー**: 静的生成による検索エンジン最適化 ### デメリット - **エコシステム**: ReactやVueと比較してライブラリが少ない - **コミュニティサイズ**: より小さなコミュニティ - **企業採用**: 大企業での採用事例がまだ限定的 - **学習リソース**: ドキュメントや学習教材が比較的少ない ## 参考ページ - [公式サイト](https://kit.svelte.dev/) - [Svelteドキュメント](https://svelte.dev/docs) - [GitHubリポジトリ](https://github.com/sveltejs/kit) - [アダプター一覧](https://kit.svelte.dev/docs/adapters) - [チュートリアル](https://learn.svelte.dev/) ## 書き方の例 ### 1. インストールとセットアップ **SvelteKitプロジェクトの作成** ```bash # 新しいSvelteKitプロジェクトを作成 npm create svelte@latest my-sveltekit-app cd my-sveltekit-app # 依存関係をインストール npm install # 開発サーバーを起動 npm run dev ``` **SSG用のsvelte.config.js** ```javascript import adapter from '@sveltejs/adapter-static'; export default { kit: { adapter: adapter({ // 出力ディレクトリ設定 pages: 'build', assets: 'build', fallback: undefined, precompress: false, strict: true }), paths: { base: process.env.NODE_ENV === 'production' ? '/my-site' : '' } } }; ``` ### 2. ページ作成とルーティング **src/routes/+page.svelte** ```svelte <script> // ページメタデータ import { page } from '$app/stores'; export let data; </script> <svelte:head> <title>ホームページ - SvelteKitサイト</title> <meta name="description" content="SvelteKitで構築した静的サイト" /> </svelte:head> <main> <h1>SvelteKitサイトへようこそ</h1> <p>高速で軽量な静的サイトです。</p> <a href="/blog">ブログを見る</a> </main> <style> main { max-width: 800px; margin: 0 auto; padding: 2rem; } h1 { color: #ff3e00; text-align: center; } </style> ``` **src/routes/+layout.js** ```javascript // 全ページの事前レンダリングを有効化 export const prerender = true; ``` ### 3. 動的ルートとデータ取得 **src/routes/blog/[slug]/+page.js** ```javascript import { error } from '@sveltejs/kit'; /** @type {import('./$types').PageLoad} */ export async function load({ params }) { try { const post = await import(`../../../posts/${params.slug}.md`); return { content: post.default, meta: post.metadata }; } catch (e) { throw error(404, `投稿が見つかりません: ${params.slug}`); } } // 動的ルートの事前レンダリング設定 export const prerender = true; /** @type {import('./$types').EntryGenerator} */ export function entries() { return [ { slug: 'first-post' }, { slug: 'second-post' }, { slug: 'third-post' } ]; } ``` **src/routes/blog/[slug]/+page.svelte** ```svelte <script> export let data; </script> <svelte:head> <title>{data.meta.title} - ブログ</title> <meta name="description" content={data.meta.description} /> </svelte:head> <article> <header> <h1>{data.meta.title}</h1> <time datetime={data.meta.date}>{data.meta.date}</time> </header> <div class="content"> <svelte:component this={data.content} /> </div> </article> <style> article { max-width: 800px; margin: 0 auto; padding: 2rem; } header { margin-bottom: 2rem; border-bottom: 1px solid #eee; padding-bottom: 1rem; } .content { line-height: 1.6; } </style> ``` ### 4. 状態管理 **src/lib/stores.js** ```javascript import { writable } from 'svelte/store'; // テーマ管理 export const theme = writable('light'); // ユーザー設定 export const userSettings = writable({ language: 'ja', notifications: true }); // カウンター例 export const count = writable(0); ``` **src/routes/settings/+page.svelte** ```svelte <script> import { theme, userSettings } from '$lib/stores.js'; function toggleTheme() { theme.update(t => t === 'light' ? 'dark' : 'light'); } </script> <main> <h1>設定</h1> <section> <h2>外観</h2> <label> <input type="radio" bind:group={$theme} value="light" /> ライトテーマ </label> <label> <input type="radio" bind:group={$theme} value="dark" /> ダークテーマ </label> </section> <section> <h2>言語設定</h2> <select bind:value={$userSettings.language}> <option value="ja">日本語</option> <option value="en">English</option> </select> </section> </main> ``` ### 5. フォーム処理 **src/routes/contact/+page.server.js** ```javascript import { fail } from '@sveltejs/kit'; /** @type {import('./$types').Actions} */ export const actions = { default: async ({ request }) => { const data = await request.formData(); const name = data.get('name'); const email = data.get('email'); const message = data.get('message'); // バリデーション if (!name || !email || !message) { return fail(400, { error: '全ての項目を入力してください', name, email, message }); } // メール送信処理(実装は省略) console.log('お問い合わせ受信:', { name, email, message }); return { success: true }; } }; ``` **src/routes/contact/+page.svelte** ```svelte <script> import { enhance } from '$app/forms'; export let form; </script> <svelte:head> <title>お問い合わせ</title> </svelte:head> <main> <h1>お問い合わせ</h1> {#if form?.success} <div class="success"> お問い合わせありがとうございました。 </div> {/if} {#if form?.error} <div class="error"> {form.error} </div> {/if} <form method="POST" use:enhance> <label> お名前 <input type="text" name="name" value={form?.name ?? ''} required /> </label> <label> メールアドレス <input type="email" name="email" value={form?.email ?? ''} required /> </label> <label> メッセージ <textarea name="message" required>{form?.message ?? ''}</textarea> </label> <button type="submit">送信</button> </form> </main> <style> form { max-width: 500px; margin: 0 auto; } label { display: block; margin-bottom: 1rem; } input, textarea { width: 100%; padding: 0.5rem; border: 1px solid #ccc; border-radius: 4px; } button { background: #ff3e00; color: white; padding: 0.75rem 1.5rem; border: none; border-radius: 4px; cursor: pointer; } .success { background: #d4edda; color: #155724; padding: 1rem; border-radius: 4px; margin-bottom: 1rem; } .error { background: #f8d7da; color: #721c24; padding: 1rem; border-radius: 4px; margin-bottom: 1rem; } </style> ``` ### 6. デプロイとビルド **静的サイトのビルド** ```bash # 静的サイトを生成 npm run build # ローカルでプレビュー npm run preview ``` **package.jsonのスクリプト例** ```json { "scripts": { "dev": "vite dev", "build": "vite build", "preview": "vite preview", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" } } ``` **GitHub Pagesへのデプロイ設定** ```javascript // svelte.config.js import adapter from '@sveltejs/adapter-static'; const dev = process.argv.includes('dev'); export default { kit: { adapter: adapter({ fallback: '404.html' }), paths: { base: dev ? '' : process.env.BASE_PATH } } }; ```