コンテンツにスキップ

第3章:ディレクトリ構造とコーディング標準

チーム開発で最も重要なのは、「誰が作っても同じ場所に同じ形式でコードが存在すること」 です。

ローカルディレクトリの推奨配置

Section titled “ローカルディレクトリの推奨配置”

ソースコード(Git リポジトリ)は、「デスクトップ」や「書類」ではなく、専用の短いパス に配置するのが鉄則です。

ホームディレクトリ直下に Develop または Projects フォルダを作成します。

/Users/ユーザー名/Cursor/
└── 組織名(またはクライアント名)/
├── project-a/ <-- リポジトリ
├── project-b/
└── team-guidelines/
  • パスの例: ~/Cursor/team-guidelines
  • メリット: OS 標準のアクセス権限トラブルが起きにくく、ターミナルや Cursor からの移動もスムーズです。

C ドライブ直下に devProjects フォルダを作成します。

C:\cursor\
└── 組織名(またはクライアント名)\
├── project-a\ <-- リポジトリ
├── project-b\
└── team-guidelines\
  • パスの例: C:\cursor\team-guidelines
  • メリット:
    • Windows 特有の 「パスの 260 文字制限(MAX_PATH 問題)」 による node_modules のビルドエラーを回避できます。
    • ユーザー名フォルダ配下に置かないことで、ユーザー名に日本語が含まれている場合のエラーを防げます。

チームで厳守すべき4つの絶対ルール

Section titled “チームで厳守すべき4つの絶対ルール”

ルール 1:クラウド同期フォルダ配下には置かない

Section titled “ルール 1:クラウド同期フォルダ配下には置かない”
  • node_modules やビルド生成物(.astro / dist)は数万個のファイルで構成されます。クラウド同期が走ると、PC が極端に重くなる・ファイルがロックされてビルドが失敗する・Git の履歴が壊れる といった致命的な不具合が発生します。
  • コードのバックアップや共有は、すべて GitHub が担当します。

ルール 2:パスに日本語(全角)とスペースを含めない

Section titled “ルール 2:パスに日本語(全角)とスペースを含めない”
  • NG: C:\Users\山田 太郎\デスクトップ\練習 プロジェクト\
  • OK: C:\cursor\practice-project\

Node.js ツールや CLI コマンド、AI ツールが空白やマルチバイト文字(日本語)を正しくエスケープできず、原因不明のエラーの原因になります。

ルール 3:改行コードの統一(.gitattributes

Section titled “ルール 3:改行コードの統一(.gitattributes)”

Mac(LF)と Windows(CRLF)が混在すると、「何も変更していないのに全行が変更された扱いになる」という事故が起きます。

プロジェクトのルートに .gitattributes を1枚置いてリポジトリに含めておくことで、OS に関わらず自動的に LF に統一されます。

* text=auto eol=lf

ルール 4:.env(機密情報)はローカル管理のみ

Section titled “ルール 4:.env(機密情報)はローカル管理のみ”
  • API キーやトークンを記載した .env はローカル PC の各リポジトリ直下にのみ保存し、決して GitHub やチャットツールに生テキストで流さないこと。
  • チームメンバーへの共有は「パスワード管理ツール(1Password 等)」を使うか、設定値の雛形として .env.example(値は空)をリポジトリで共有します。

案件終了後・アーカイブの片付けルール

Section titled “案件終了後・アーカイブの片付けルール”

Web 制作チームでありがちなのが、「過去案件で PC の SSD 容量が圧迫される」問題です。

[進行中の案件] ──► ローカルPC(C:\dev または ~/Develop)で開発
▼ (納品完了・運用フェーズへ)
[ローカルの片付け] ──► `node_modules` と `dist` フォルダだけ削除する
└─► ソースコード本体はGitHubに完全保存されているため、
手元のコードは容量数MB程度になり、いつでも `npm install` で復元可能

案件が終わったら、Cursor や Composer に 「このプロジェクトの node_modulesdist フォルダを削除して容量を空けて」 と指示するだけで、数十 MB〜数百 MB の空き容量を即座に回収できます。

全案件で共通利用する標準構成です。

my-project/
├── public/ # ファビコン、robots.txt、サイトマップ等の静的配置ファイル
├── src/
│ ├── assets/ # デザイン用画像・SVGアイコン(Astro最適化対象)
│ │ ├── images/
│ │ └── icons/
│ ├── components/ # 再利用可能なUIパーツ
│ │ ├── common/ # Header, Footer, Button, Breadcrumb など
│ │ └── sections/ # Hero, NewsSection などページを構成する大型ブロック
│ ├── layouts/ # ページ共通レイアウト(SEOメタタグ、OGP設定を含む)
│ │ ├── BaseLayout.astro
│ │ └── PostLayout.astro
│ ├── libs/ # 外部SDK初期化・ユーティリティ関数
│ │ ├── microcms.ts # microCMSクライアント設定・API関数
│ │ └── date.ts # 日付フォーマット関数(dayjsやIntl利用)
│ ├── pages/ # ファイルベースルーティング
│ │ ├── index.astro # トップページ
│ │ ├── about.astro # 固定ページ
│ │ ├── news/
│ │ │ ├── index.astro # お知らせ一覧(ページネーション対応)
│ │ │ └── [id].astro # お知らせ詳細(ダイナミックルーティング)
│ │ └── api/ # Cloudflare Pages Functions / SSRエンドポイント
│ │ └── preview.ts # 下書きプレビュー用API(第4章参照)
│ ├── styles/
│ │ └── global.css # Tailwind基本設定・フォント読み込み
│ └── types/ # TypeScript型定義
│ └── microcms.ts # 記事・お知らせ・カテゴリ等のスキーマ型定義
├── .cursorrules # Cursorチームルール(第2章)
├── astro.config.mjs # Astro設定ファイル(Tailwind・Cloudflareアダプター等)
└── tailwind.config.mjs # Tailwindデザインシステム定義

レイアウト・SEO・OGP 共通化ルール

Section titled “レイアウト・SEO・OGP 共通化ルール”

全ページで共通の <head> 管理を行うため、SEO・OGP・Favicon は BaseLayout に集約し、Props で各ページからメタ情報を受け取ります。

src/layouts/BaseLayout.astro
---
interface Props {
title: string;
description?: string;
ogImage?: string;
noindex?: boolean;
}
const {
title,
description = "デフォルトのサイト説明文(BtoB企業・大学名など)",
ogImage = "/ogp-default.png",
noindex = false,
} = Astro.props;
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
const socialImageURL = new URL(ogImage, Astro.site);
---
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{title ? `${title} | サイト名` : "サイト名"}</title>
<meta name="description" content={description} />
<link rel="canonical" href={canonicalURL} />
{noindex && <meta name="robots" content="noindex,nofollow" />}
<!-- OGP / Twitter Cards -->
<meta property="og:type" content="website" />
<meta property="og:url" content={canonicalURL} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={socialImageURL} />
<meta name="twitter:card" content="summary_large_image" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
</head>
<body class="min-h-screen flex flex-col bg-white text-gray-900 font-sans antialiased">
<slot name="header" />
<main class="flex-grow">
<slot />
</main>
<slot name="footer" />
</body>
</html>

画像最適化ルール(astro:assets の徹底)

Section titled “画像最適化ルール(astro:assets の徹底)”
  • ローカル画像(src/assets/)は、必ず Astro の <Image /> コンポーネントを使用し、自動で WebP 変換・リサイズ・Lazy Load・レイアウトシフト(CLS)防止 を行います。
  • <img> タグの生書きは原則禁止です。
src/components/sections/Hero.astro
---
import { Image } from 'astro:assets';
import heroImage from '../../assets/images/hero-visual.jpg';
---
<section class="relative overflow-hidden bg-gray-50 py-16 md:py-24">
<div class="container mx-auto px-4 grid md:grid-cols-2 gap-8 items-center">
<div>
<h1 class="text-3xl md:text-5xl font-bold tracking-tight text-gray-900 leading-tight">
次世代の教育を、<br />ここから。
</h1>
<p class="mt-4 text-lg text-gray-600">大学・BtoBサイトに最適な高速Webプラットフォーム。</p>
</div>
<div>
<!-- width/heightは元画像の比率から自動計算され、WebP形式で配信されます -->
<Image
src={heroImage}
alt="キャンパスの風景"
class="rounded-2xl shadow-xl w-full h-auto object-cover"
loading="eager"
/>
</div>
</div>
</section>

ファーストビューの画像のみ loading="eager" を指定します。

  • 任意の値(Arbitrary values: w-[342px] など)の乱用禁止
    • レイアウトのブレを防ぐため、原則として tailwind.config.mjs で定義したスペーシングやフォントサイズ、カラーパレット(primary, secondary 等)を使用します。
  • インタラクションの最小 JavaScript 原則
    • モバイルのハンバーガーメニューやアコーディオンなど、極力シンプルな JavaScript(Vanilla TS)または HTML 標準の <details>/<summary> タグで実装し、サイト全体の軽量性を維持します。