zfb
GitHub リポジトリ

検索したい単語を入力

いつでも検索バーを開ける

プロジェクト構造

デフォルトテンプレートが配置するすべてのファイルとディレクトリを案内する。

zfb new my-site を実行すると、basic-blog テンプレートが小さくも完結したプロジェクトを配置します。各ディレクトリが何のためのものかを知っておくと、これ以降のドキュメントをぐっと読み進めやすくなります。

my-site/
├── pages/
│   ├── index.tsx
│   ├── about.tsx
│   ├── 404.tsx
│   └── blog/
│       └── [slug].tsx
├── layouts/
│   └── default.tsx
├── components/
│   ├── callout.tsx
│   ├── theme-toggle.tsx
│   └── zfb-shim.d.ts
├── content/
│   └── blog/
│       ├── hello-zfb.mdx
│       ├── markdown-showcase.md
│       └── styling-with-zudo-wind.md
├── lib/
│   └── types.ts
├── styles/
│   └── global.css
├── mdx-components.tsx
├── zfb.config.ts
├── package.json
├── tsconfig.json
├── README.md
└── .gitignore

ここに並ぶファイルはすべて、読んで書き換えられることを前提にしています。隠されたレイヤーも、触らずにおくべき生成コードもありません。

pages/

ファイルシステムルーティングはここに置かれます。pages/ 配下のすべてのページファイル(.tsx・.ts・.jsx・.js・.mdx・.md・.html)がルートになります。完全なコントラクトは ルーティング を参照してください。

  • pages/index.tsx → /

  • pages/about.tsx → /about

  • pages/blog/[slug].tsx → /blog/:slug(動的ルート — 解決された slug ごとに 1 つの HTML ファイル)

  • pages/docs/[...slug].tsx → キャッチオール、任意の深さにマッチ

テンプレートには静的ルートが 3 つ、動的ルートが 1 つ含まれます。index.tsx は getStaticProps() で全記事を新しい順に一覧し、about.tsx はデータ取得を一切行わない静的ページ、blog/[slug].tsx は paths() をエクスポートします。zfb はビルド時にこの paths() を呼び出し、[slug] をコレクションのエントリごとに 1 つの HTML ファイルへ展開します。完全な API は 動的ルート を参照してください。

特別な意味を持つファイル名は 404.tsx だけです。トップレベルの pages/404.tsx は dist/404/index.html ではなく、フラットな dist/404.html を出力します。これは zfb preview が — そしてたいていの静的ホスティングが — マッチしないリクエストに対して配信するファイルです。

テンプレートが動的ルートを 1 つで止めているのは意図的です。ページ分割された一覧やタグごとのアーカイブは、いずれも同じ paths() のコントラクトの上に数行を足すだけで書けるため、テンプレートはそれらを同梱せず README.md から次の一歩としてリンクしています。paginate() はコレクションをページごとのルートに変換し、pages/tags/[tag].tsx ルートは記事のフロントマターにすでにある tags で記事をグループ化します。

layouts/

再利用可能なページラッパーです。layouts/default.tsx はすべてのページが import するシェルで、<head>・ヘッダー・フッターに加えて、保存されたテーマを最初のフレームより前に適用するインラインスクリプトを担います。レイアウトは素の TSX コンポーネントなので、好きなように合成できます。

components/

素のコンポーネントと 島 です。テンプレートには 2 つのコンポーネントと 1 つの型宣言が含まれます。

  • components/callout.tsx は、ベースとなる Callout に加えて Note・Tip・Important・Warning・Caution の 5 つの名前付きラッパーをエクスポートします。この 5 つの名前は GitHub アラート機能によって固定されています。この機能は > [!NOTE] の引用ブロックを、レンダリング前に <Note> 要素へ書き換えます。

  • components/theme-toggle.tsx はテンプレート唯一の "use client" 島です。ダークモードを切り替えるもので、ブラウザへ JavaScript を出力する唯一のコンポーネントでもあります。ファイル先頭の "use client" ディレクティブこそが、コンポーネントをクライアントサイドの島に変えるものです。これがないコンポーネントはサーバー上でのみレンダリングされます。考え方の全体像は Islands にあります。

  • components/zfb-shim.d.ts はコンポーネントではありません。対応するベアの zfb インポート群を TypeScript に宣言し、@takazudo/zfb の公開エントリからそれぞれの型を再エクスポートします。ビルドツールは SSR、島のスキャン、クライアントバンドル、JSX pragma の判定、zudo-wind のクラス抽出でこれらのエイリアスを解決します。設定ローダーは zfb/config を別途、内部のランタイム専用スタブへ対応づけます。ビルド時のエイリアスは TypeScript を設定せず、zfb check も compilerOptions.paths を注入しません。エディタと zfb check は、プロジェクトの tsconfig に含まれるこのシムでベア指定子を解決します。標準テンプレートは components/ を含みます。既存のシムがある場合は、不足しているモジュール宣言を追加してください。宣言ファイル全体はベアの zfb インポートの型付けを参照してください。

content/

コンテンツコレクションです。content/blog/ は blog コレクションの 3 つのシードエントリを保持します。名前付きディレクトリ内の Markdown・MDX ファイルで、ページから getCollection("blog") でクエリできます。

  • hello-zfb.mdx — ページがどのように HTML になるか、そして MDX が素の Markdown に何を加えるか。

  • markdown-showcase.md — テンプレートが有効にしている markdown 機能(テーブル、打ち消し線、タスクリスト、フットノート、アラート、エンリッチされたコードブロック、見出しマーカー TOC)の実例を、リファレンスページへのリンク付きで掲載。

  • styling-with-zudo-wind.md — スターターのユーティリティトークン、手書き CSS、ダークモードの設定を説明します。

コレクションスキーマは zfb.config.ts の collections 配下で宣言します。クエリ API については Content Collections を参照してください。

mdx-components.tsx

レンダリングされるすべてのコンテンツエントリに適用される、プロジェクトルートのコンポーネントマップです。zfb はこのファイルを zfb.config.ts の隣で検出してビルドに取り込み、ページがレンダリングされる前にその default export をインストールします。そのため <entry.Content /> は、呼び出しごとの配線なしにこのマップを拾います。

テンプレートのマップは、components/callout.tsx の 5 つのアラートコンポーネントをエクスポートします。素の .md 記事で > [!NOTE] が動くのはこれがあるからです。githubAlerts 機能は <Note> 要素を生成し、解決できない PascalCase の名前はレンダリング時に例外を投げます。マージ順は defaultComponents → このファイル → 呼び出し側の components prop なので、個別のページからローカルに上書きすることもできます。MDX Components を参照してください。

lib/

共有の TypeScript ユーティリティです。テンプレートには lib/types.ts が含まれ、ページやコンポーネント全体で使われるフロントマターとエントリの型を持ちます。ここにフレームワークのマジックはありません。必要な場所で import する素の TypeScript モジュールです。

styles/

グローバル CSS です。styles/global.css がエントリポイントで、layouts/default.tsx から import します。サイトのベーススタイルと .prose ブロックは手書き CSS にあります。zfb.config.ts の wind オブジェクトはスターターのユーティリティトークン、ブレークポイント、リセット、data-theme による dark バリアントを設定します。wind の設定はスタイルシートのディレクティブではなくデータです。

この分割は意図的なものです。.tsx ファイル内のページの外枠は zudo-wind のユーティリティをインラインで使いますが、Markdown が生成するのはユーティリティクラスの届かない素のタグです。後者は CSS 側で一度だけスタイルを当て、class="prose" でオプトインします。スターターは wind を明示的に設定します。他のプロジェクトではキーを省略すると空の有効な設定になり、wind: false なら手書き CSS だけを使います。スタイリングと zudo-wind の設定を参照してください。

public/

サイトのルートからそのまま配信される静的アセットです。テンプレートは public/ ディレクトリをスキャフォールドしません。静的ファイルを配信する必要が出たときに作成してください。favicon.ico・robots.txt・SVG・ラスター画像・フォント・マニフェストファイルなど、絶対 URL で参照したいバイナリをここに置きます。このディレクトリは URL には現れません。public/logo.svg は zfb dev でも zfb build 後でも /logo.svg で到達できます。

これらのファイルは TSX・MDX・CSS から URL で参照します。

<img src="/logo.svg" alt="" width={128} height={32} />
<link rel="icon" href="/favicon.ico" />

静的アセットにバンドラスタイルの import(import logo from "./logo.svg")を使わないでください。zfb は public/ に対してアセットパイプラインを実行しません。このディレクトリはそのままのミラーであり、ファイルは相対パスに一致する URL で出力されます。

zfb.config.ts で base が設定されている場合(例: base: "/pj/site/")、public/ 内のファイルもそのプレフィックス配下で配信されます。public/logo.svg → /pj/site/logo.svg です。同じ前置がビルド時にも行われるため、プレフィックスは dev と prod で一貫します。

public/ を使う場合と島向けに TSX import を使う場合の使い分けを含む完全なリファレンスは、静的アセット を参照してください。

zfb.config.ts

テンプレートがスキャフォールドするのは TypeScript の設定ファイルです。オブジェクトを defineConfig() で包むため、完全な型チェックと IDE 補完が得られます。

import { defineConfig } from "zfb/config";

export default defineConfig({
  wind: {
    spec: 1,
    reset: "owned-v1",
    tokens: {
      spacingUnit: "0.25rem",
      colors: { accent: "var(--color-accent)" },
      sizes: { "2xl": "42rem" },
      // The starter supplies the rest of its explicit palette and scales here.
    },
    breakpoints: { sm: { minWidthPx: 640 } },
    dark: { attribute: "data-theme", value: "dark" },
    authoredClasses: { prose: true },
  },
  collections: [{ name: "blog", path: "content/blog", schema: { /* … */ } }],
  markdown: {
    gfm: { taskListItem: true, footnoteDefinition: true },
    features: { githubAlerts: true, codeEnrichment: {}, headingMarkerToc: true },
  },
});

この短い例は、スターターの明示的な wind 設定と blog コレクション、markdown のオプトインを示します。outDir と publicDir はデフォルトを使い、パレットとスケールの残りは実際の設定ファイルで宣言します。GFM のタスクリストとフットノート、GitHub アラート、コードブロックのエンリッチメント、見出しマーカー TOC が有効です。全機能は Markdown 機能を参照してください。

設定ファイルは camelCase スキーマを使います。主なキーは outDir(デフォルト "dist")、publicDir(デフォルト "public")、host(デフォルト "localhost")、port(zfb dev は 3000、zfb preview は 4321 にフォールバック)、wind、collections、plugins です。完全なスキーマは defineConfig を参照してください。

outDir は zfb dev、zfb build、zfb preview のすべてで尊重されます。build と preview では CLI の --outdir が config の outDir より優先され、組み込みのフォールバックは dist/ です。

素の zfb.config.json もレガシーのフォールバックとして受け付けられます。スキーマは同一ですが、型も defineConfig() も得られません。両方のファイルが存在する場合は .ts が優先されます。

package.json、tsconfig.json、README.md、.gitignore

標準的なプロジェクトの設定ファイル群です。package.json はプロジェクトの依存関係と dev、build、preview、typecheck の 4 つのスクリプトを宣言します。所有 JSX ランタイムは @takazudo/zfb のサブパスで、別のフレームワークパッケージは不要です。zfb new は zfb のパッケージをスキャフォールドに使用した CLI のバージョンへ厳密に固定し、新しいリリースへ静かに移らないようにします。

tsconfig.json では jsx と jsxImportSource を指定し、TypeScript が zfb と同じランタイムに対して JSX を検査するようにします。zfb build と zfb dev はページ、コンポーネント、アイランドの JSX を自動変換と @takazudo/zfb/zudo-react でコンパイルします(ファイル単位の @jsxImportSource pragma がある場合を除く)。これらの tsconfig 設定は読みません。また、~/* をプロジェクトルートに解決するパスエイリアスを設定します。ルート直下のファイルを import するときは ~/lib/types のように ~/ を使ってください。lib/types のようなベア import はプロジェクトルート基準にはなりません。このエイリアスは baseUrl なしで使え、テンプレート内の import も一貫してこの形式です。

README.md は同じツリーの短い案内に加えて、このスターターで有効になっている markdown 機能と、利用可能だが無効にしてある機能を、それぞれリファレンスページへのリンク付きで表にまとめたものです。

同梱の .gitignore は dist/ と node_modules/ を除外します。また、islands、プラグイン、module worker のバンドル中に作られる一時ファイルも除外します。これらは通常実行後に削除されますが、プロセスが中断された場合も無視されます。

Revision History

作成更新