はじめに

使える軽量なブログを土日で作る という記事に触発され、このブログの作成を思い立ちました。

Web開発やsvelteの知識は皆無で、ゼロからのスタートだったため土日とはいかずに5日程度かかってしまいましたが、無事に自分のブログを立ち上げることができました。

この記事では、この開発過程で得た知見を共有します。

また、コードはGitHubで公開されていますので、そちらも参考にしてください。


また、開発にあたりこの記事には非常にお世話になりました。ブログを作りたい方は、読んでみることを強くおすすめします。

SvelteでMarkdownブログを作成する手順 - Naotoshi Fujita

技術スタック

今回構築したブログの技術スタックは以下の通りです。

  • フレームワーク: SvelteKit (TypeScript + SCSS)
  • ホスティング: Cloudflare Pages
  • Markdown処理:

記事の管理はMarkdownファイルで行い、以下のようなfront matterを持たせています。

  • title: 記事のタイトル
  • slug: 記事のURLになる文字列
  • date: 作成日
  • updateDate: 更新日 (任意)
  • tags: タグ (配列)

開発で得た知見

1. Svelteのドキュメント・チュートリアルが親切

公式のドキュメントチュートリアルが非常に丁寧で、初学者に優しいです。

私は公式チュートリアルのBasic SvelteとBasic SvelteKitの前半だけを読んでから開発を始めました。

2. SvelteKitのデータフロー

SvelteKitでは、以下のような流れでデータを受け渡し、ページを描画しています。

  1. +page.server.tsファイル内でexport async function load() { ... }を定義する。
  2. このload関数が返した値は、同じディレクトリにある+page.sveltelet { data } = $props()dataとして受け取れる。

+page.server.tsload関数の返り値が{ posts: getPosts() }のようなオブジェクトであれば、+page.svelteではdata.postsとしてアクセスできます。

3. Markdownの一括読み込み

Viteのimport.meta.glob()を使用することで、指定したパス(以下の場合は$postsディレクトリ以下の全.mdファイル)に一致するファイルを一括でインポートできます。

// src/lib/getPosts.ts

const markdowns: Record<string, { default: string }> = import.meta.glob("$posts/**/*.md", {
    eager: true,
    query: "?raw",
});

オプションについては以下の通りです。

  • eager: trueを指定すると、ファイルの内容が返されます。falseの場合はファイルの内容を返す非同期関数が返されます。(参考)
  • query: "?raw"を指定すると、ファイルの中身が純粋な文字列として読み込まれます。 Markdownファイルをテキストとして扱いたい場合は、この指定が必須のようでした。

ただ、パスを指定する際、"../../"のような指定はできません。次で説明するパスのエイリアスを利用してください。

4. パスのエイリアス

svelte.config.jsでエイリアスを設定すると、importの際に$posts/...のようにアクセスすることが出来ます。(参考)

私は以下のようにして利用しました。

  • src/lib$lib(デフォルトで定義済)

    型定義(types.ts)や、汎用的な関数(記事取得、日付フォーマットなど)をこのディレクトリに置きます。import { TypeName } from '$lib/types'のようにして、簡単にインポートできます(拡張子は不要です)。

  • src/posts$posts

    記事となるMarkdownファイルを配置します。年ごとにディレクトリをつくり、そこに記事を作っていく予定です。

  • src/css$css

    global.scssを配置しています。サイト全体の背景色やヘッダー・フッターのスタイルなど、共通のCSSはここにまとめ、src/routes/+layout.svelteで読み込んでいます。 これにより、:global()の利用を回避できます。

5. 静的レンダリング

SvelteKitでは、src/routes/+layout.server.tsで以下のように記述すると静的レンダリングされるようになります。(参考)

// src/routes/+layout.server.ts

export const prerender = true;

この設定により、ビルドを実行すると全てのページが静的なHTMLファイルとして生成されます。

ユーザーがアクセスした際、サーバーはHTMLを返すだけなので表示が非常に高速になり、サーバー負荷の軽減に繋がります。

6. Docker環境での注意点

Dockerで開発をする場合、そのままの設定では開発サーバーを起動してもホストOSのブラウザからアクセスできない、という注意点があります。

これを解決するには、vite.config.tsserver: { host: true }の設定を追加してください。

// vite.config.ts

import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [sveltekit()],
  server: {
    host: true,
  },
});

この設定を追加することで、Dockerコンテナ内で実行されている開発サーバーに、ホストのブラウザからhttp://localhost:5173のようにアクセスできるようになります。

7. SCSSのシンタックスハイライト

これは初歩的なミスですが、Svelteファイル内でSCSSのシンタックスハイライトが効かない、ということがありました。原因は単純で、<style>タグにlang="scss"を書き忘れていただけでした。

<style lang="scss">
  ...
</style>

余談ですが、cssでemremを間違えて2時間ほど溶かしたこともありました。気をつけましょう。

まとめ

知識ゼロからでも、自分なりに満足のいくブログをつくることができました。

この記事が、これからブログを作ろうとしている方の参考になれば嬉しいです。