Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

README.md

第9章: 応用・総合制作

学習目標

これまで学んだ知識を統合し、実践的なWebサイトを制作します。

  • プロジェクト企画
  • 設計とワイヤーフレーム
  • 実装
  • テストとデバッグ
  • 公開と改善サイクル

成果物: 個人Webサイト完成


0. なぜ「設計」が重要なのか?チュートリアルから実践へ

0-1. チュートリアルと実際のプロジェクトの違い

これまでの章では、手順に従ってコードを書いてきました。しかし、自分で何かを作るとなると、まったく違うスキルが必要になります。

チュートリアル形式
┌──────────────────────────────────────┐
│ 1. 手順が決まっている                 │
│    → 次に何をするか明確               │
│                                      │
│ 2. 答えが用意されている               │
│    → 詰まっても解決策がある           │
│                                      │
│ 3. スコープが限定的                   │
│    → ToDoアプリだけ、など             │
│                                      │
│ 4. エラーハンドリングは最小限         │
│    → ハッピーパスのみ                 │
└──────────────────────────────────────┘

実際のプロジェクト
┌──────────────────────────────────────┐
│ 1. 白紙の状態から始まる               │
│    → 何を作るか自分で決める           │
│                                      │
│ 2. 正解がない                        │
│    → トレードオフを判断する           │
│                                      │
│ 3. スコープが曖昧                     │
│    → どこまで作るか決める             │
│                                      │
│ 4. 現実的な制約がある                 │
│    → 時間、予算、技術的制約           │
└──────────────────────────────────────┘

「いきなりコードを書く」の落とし穴

計画なしで作り始めた場合
┌──────────────────────────────────────┐
│ Day 1: よし、ブログを作ろう!          │
│        → トップページのコード書く      │
│                                      │
│ Day 2: あれ、記事のデータどうする?    │
│        → データ構造を考え直す          │
│        → トップページを修正            │
│                                      │
│ Day 3: カテゴリー機能も欲しい...      │
│        → また設計変更                 │
│        → 既存コードを大幅修正          │
│                                      │
│ Day 7: コードがぐちゃぐちゃ...         │
│        → モチベーション低下            │
│        → プロジェクト中断              │
└──────────────────────────────────────┘

設計してから作った場合
┌──────────────────────────────────────┐
│ Day 1-2: 企画・設計                   │
│          → 何を作るか明確化           │
│          → 必要な画面を洗い出し        │
│          → データ構造を決定            │
│                                      │
│ Day 3-6: 実装                        │
│          → 設計通りにコード書く        │
│          → 手戻りが少ない             │
│                                      │
│ Day 7: テスト・デプロイ               │
│        → 完成!                      │
└──────────────────────────────────────┘

0-2. ソフトウェア開発のライフサイクル

プロのエンジニアは、いきなりコードを書きません。プロセスに従います。

ウォーターフォール vs アジャイル

ウォーターフォール(伝統的手法)
┌──────────────────────────────────────┐
│ 1. 要件定義  │████████│ (2週間)     │
│ 2. 設計      │████████│ (2週間)     │
│ 3. 実装      │████████████│ (4週間)  │
│ 4. テスト    │████│ (1週間)         │
│ 5. リリース  │██│ (数日)           │
└──────────────────────────────────────┘

特徴:
✅ 計画的
❌ 柔軟性がない
❌ 後半で問題発覚すると大変
アジャイル(モダンな手法)
┌──────────────────────────────────────┐
│ Sprint 1 (2週間)                     │
│ 企画 → 設計 → 実装 → テスト → リリース │
│ → 最小限の機能をリリース              │
│                                      │
│ Sprint 2 (2週間)                     │
│ 企画 → 設計 → 実装 → テスト → リリース │
│ → 機能追加                           │
│                                      │
│ Sprint 3 (2週間)                     │
│ 企画 → 設計 → 実装 → テスト → リリース │
│ → さらに機能追加                      │
└──────────────────────────────────────┘

特徴:
✅ 柔軟
✅ 早期にフィードバック取得
✅ リスク分散

個人プロジェクトでのおすすめアプローチ

MVP (Minimum Viable Product) 思考
┌──────────────────────────────────────┐
│ Phase 1: MVP(最小限の機能)          │
│ ├─ 記事を表示できる                   │
│ ├─ 1ページだけ                       │
│ └─ デザインは最低限                   │
│ → まず動くものを作る                  │
│                                      │
│ Phase 2: 機能拡張                     │
│ ├─ カテゴリー機能追加                 │
│ ├─ 検索機能追加                       │
│ └─ デザイン改善                       │
│ → フィードバックを得ながら改善        │
│                                      │
│ Phase 3: 磨き上げ                     │
│ ├─ パフォーマンス最適化               │
│ ├─ SEO対策                           │
│ └─ アニメーション追加                 │
│ → 完成度を高める                      │
└──────────────────────────────────────┘

0-3. なぜワイヤーフレームを描くのか?

ワイヤーフレーム = 画面の設計図

ワイヤーフレームなしで作った場合
┌──────────────────────────────────────┐
│ 頭の中のイメージ:                     │
│ "記事カードを並べよう"                │
│                                      │
│ 実装中の悩み:                         │
│ - 何カラムにする?                    │
│ - カード内に何を表示?                │
│ - 画像のサイズは?                    │
│ - ホバーエフェクトは?                │
│                                      │
│ → 実装しながら決めるので手戻りが多い  │
└──────────────────────────────────────┘

ワイヤーフレームを描いた場合
┌──────────────────────────────────────┐
│ 紙に描いたスケッチ:                   │
│ ┌─────┐ ┌─────┐ ┌─────┐             │
│ │画像 │ │画像 │ │画像 │             │
│ │Title│ │Title│ │Title│             │
│ │Date │ │Date │ │Date │             │
│ └─────┘ └─────┘ └─────┘             │
│                                      │
│ 実装:                                │
│ → 設計通りにコード書くだけ            │
│ → 迷わない                           │
└──────────────────────────────────────┘

ワイヤーフレームの粒度

Low-Fidelity(ざっくり)
┌──────────────────────┐
│ [Header]             │
│ ┌──────────────────┐ │
│ │  Hero Section    │ │
│ └──────────────────┘ │
│ [Cards] [Cards]      │
│ [Footer]             │
└──────────────────────┘

Mid-Fidelity(そこそこ詳細)
┌──────────────────────┐
│ Logo  [Nav] [Nav]    │
│ ┌──────────────────┐ │
│ │ Title            │ │
│ │ Subtitle         │ │
│ │ [CTA Button]     │ │
│ └──────────────────┘ │
│ ┌────┐ ┌────┐       │
│ │Img │ │Img │       │
│ │Text│ │Text│       │
│ └────┘ └────┘       │
└──────────────────────┘

High-Fidelity(デザインモックアップ)
実際の色、フォント、画像を使用
→ これはデザイナーの領域

0-4. データ設計の重要性

型定義から始める習慣

プロのTypeScript開発者は、まず型を定義します。

// ❌ 悪い例: いきなり実装
function BlogPost() {
  const [post, setPost] = useState(null);
  // post の中身は何?型が分からない
  // post.title? post.name? post.content?
}

// ✅ 良い例: 型定義から
interface Post {
  id: string;
  title: string;
  content: string;
  publishedAt: Date;
  author: Author;
  tags: string[];
}

interface Author {
  id: string;
  name: string;
  avatar: string;
}

function BlogPost() {
  const [post, setPost] = useState<Post | null>(null);
  // post の構造が明確
  // post.title にアクセスできることが分かる
}

なぜ型定義が先なのか?

型定義がコントラクト(契約)になる
┌──────────────────────────────────────┐
│ バックエンドチーム                    │
│ → Post 型のデータを返すAPIを作る      │
│                                      │
│ フロントエンドチーム                  │
│ → Post 型を受け取る前提で実装         │
│                                      │
│ → 同時並行で作業できる                │
│ → 統合時にエラーが出ない              │
└──────────────────────────────────────┘

リレーションの設計

// 1対多の関係
interface User {
  id: string;
  name: string;
  posts: Post[];  // 1人のユーザーが複数の投稿
}

// 多対多の関係
interface Post {
  id: string;
  title: string;
  tags: Tag[];  // 1つの投稿が複数のタグ
}

interface Tag {
  id: string;
  name: string;
  posts: Post[];  // 1つのタグが複数の投稿に紐づく
}

0-5. コンポーネント設計のパターン

Atomic Design(原子デザイン)

コンポーネントを5つの階層に分ける考え方:

Atoms(原子)- 最小単位
├─ Button
├─ Input
├─ Label
└─ Icon

Molecules(分子)- 原子の組み合わせ
├─ SearchBox (Input + Button)
├─ FormField (Label + Input + ErrorMessage)
└─ Card (Image + Text + Button)

Organisms(有機体)- 分子の組み合わせ
├─ Header (Logo + Navigation + SearchBox)
├─ PostList (複数の Card)
└─ CommentSection (複数の Comment)

Templates(テンプレート)- レイアウト
└─ BlogTemplate (Header + Content + Sidebar + Footer)

Pages(ページ)- 実際のデータを入れたもの
└─ BlogPage (BlogTemplate + 実際の記事データ)

実例: ブログカードの分解

// ❌ 悪い例: 全部1つのコンポーネント
function BlogCard({ post }) {
  return (
    <div className="card">
      <img src={post.image} alt={post.title} />
      <div className="content">
        <h2>{post.title}</h2>
        <p>{post.excerpt}</p>
        <div className="meta">
          <span>{post.date}</span>
          <span>{post.author}</span>
        </div>
        <button>読む</button>
      </div>
    </div>
  );
}

// ✅ 良い例: 責任を分離
// Atoms
function Button({ children, onClick }) {
  return <button onClick={onClick}>{children}</button>;
}

function Badge({ text }) {
  return <span className="badge">{text}</span>;
}

// Molecules
function CardImage({ src, alt }) {
  return <img src={src} alt={alt} className="card-image" />;
}

function CardMeta({ date, author }) {
  return (
    <div className="meta">
      <span>{date}</span>
      <span>{author}</span>
    </div>
  );
}

// Organisms
function BlogCard({ post }) {
  return (
    <article className="card">
      <CardImage src={post.image} alt={post.title} />
      <div className="content">
        <h2>{post.title}</h2>
        <p>{post.excerpt}</p>
        <CardMeta date={post.date} author={post.author} />
        <Button onClick={() => navigate(post.url)}>
          読む
        </Button>
      </div>
    </article>
  );
}

なぜこうするのか?

利点
┌──────────────────────────────────────┐
│ 1. 再利用性                          │
│    Button は他のコンポーネントでも使える │
│                                      │
│ 2. テストしやすい                     │
│    小さい単位でテストできる           │
│                                      │
│ 3. 変更に強い                        │
│    Button のデザイン変更は1箇所だけ   │
│                                      │
│ 4. チーム開発しやすい                 │
│    担当を分けられる                   │
└──────────────────────────────────────┘

0-6. 状態管理の設計

どこに状態を置くか?

状態のスコープ
┌──────────────────────────────────────┐
│ ローカル状態 (useState)               │
│ ├─ モーダルの開閉状態                 │
│ ├─ フォームの入力値                   │
│ └─ ローディング状態                   │
│                                      │
│ コンポーネント間の共有 (Context)      │
│ ├─ テーマ(ライト/ダーク)            │
│ ├─ 言語設定                          │
│ └─ ユーザー情報                       │
│                                      │
│ グローバル状態 (Zustand/Jotai)        │
│ ├─ ショッピングカート                 │
│ ├─ 通知                              │
│ └─ 複雑なフォーム                     │
│                                      │
│ サーバー状態 (SWR/React Query)        │
│ ├─ APIから取得したデータ              │
│ ├─ キャッシュ                        │
│ └─ リアルタイムデータ                 │
└──────────────────────────────────────┘

Props Drilling問題

// ❌ 悪い例: Props を何階層も渡す
function App() {
  const [user, setUser] = useState(null);
  return <Layout user={user} />;
}

function Layout({ user }) {
  return <Header user={user} />;
}

function Header({ user }) {
  return <UserMenu user={user} />;
}

function UserMenu({ user }) {
  return <Avatar user={user} />;
}

function Avatar({ user }) {
  return <img src={user.avatar} />;
}

// ✅ 良い例: Context で共有
const UserContext = createContext(null);

function App() {
  const [user, setUser] = useState(null);
  return (
    <UserContext.Provider value={user}>
      <Layout />
    </UserContext.Provider>
  );
}

function Avatar() {
  const user = useContext(UserContext);
  return <img src={user.avatar} />;
}

0-7. テストの重要性

なぜテストを書くのか?

テストなしの開発
┌──────────────────────────────────────┐
│ Day 1: 新機能Aを実装                  │
│        → 動作確認OK                   │
│                                      │
│ Day 2: 新機能Bを実装                  │
│        → Aが壊れていることに気づかない │
│                                      │
│ Day 3: バグ報告                       │
│        → 原因調査に時間がかかる        │
│        → 修正したら別の機能が壊れる    │
└──────────────────────────────────────┘

テストありの開発
┌──────────────────────────────────────┐
│ Day 1: 新機能A実装 + テスト書く        │
│        → テストパス                   │
│                                      │
│ Day 2: 新機能B実装                    │
│        → テスト実行                   │
│        → Aのテストが失敗!            │
│        → すぐに問題を発見して修正      │
└──────────────────────────────────────┘

テストの種類

テストピラミッド
        △
       /E2E\ ← 少ない
      /─────\
     / 統合  \ ← 中程度
    /─────────\
   / ユニット  \ ← 多い
  /─────────────\

ユニットテスト:
→ 個別の関数・コンポーネントをテスト
→ 実行が速い
→ たくさん書く

統合テスト:
→ 複数のコンポーネントの連携をテスト
→ 中程度の速度
→ 重要な部分をテスト

E2Eテスト:
→ ユーザー視点で全体をテスト
→ 実行が遅い
→ 主要なフローのみテスト

0-8. デバッグの技術

問題解決のアプローチ

デバッグの手順
┌──────────────────────────────────────┐
│ 1. 問題を再現する                     │
│    → どの操作で起きる?               │
│    → 毎回起きる?時々起きる?         │
│                                      │
│ 2. 問題を切り分ける                   │
│    → データの問題?ロジックの問題?   │
│    → どのコンポーネントで起きる?     │
│                                      │
│ 3. 仮説を立てる                       │
│    → 「このif文が原因では?」         │
│                                      │
│ 4. 検証する                          │
│    → console.log で値を確認           │
│    → デバッガーでステップ実行         │
│                                      │
│ 5. 修正する                          │
│    → テストを追加                     │
│    → 同じ問題が起きないようにする     │
└──────────────────────────────────────┘

効果的なログの取り方

// ❌ 悪い例
console.log('ここ');
console.log('あそこ');
console.log(data);

// ✅ 良い例
console.log('UserProfile: データ取得開始');
console.log('UserProfile: 取得したデータ:', {
  userId: data.id,
  userName: data.name,
  timestamp: new Date()
});
console.log('UserProfile: レンダリング開始');

1. プロジェクトのアイデア

1-1. おすすめプロジェクト

初級:

  • 個人ブログ
  • ポートフォリオサイト
  • ランディングページ

中級:

  • ToDoアプリ(高機能版)
  • レシピ共有サイト
  • 読書記録アプリ

上級:

  • SNS風アプリ
  • Eコマースサイト
  • SaaS(Software as a Service)

1-2. プロジェクトの選び方

チェックリスト:

  • ✅ 自分が使いたいものか
  • ✅ 技術的に実現可能か
  • ✅ 2-4週間で完成できるか
  • ✅ ポートフォリオに載せたいか

2. 設計フェーズ

2-1. 要件定義

機能要件:

  • ユーザーができること
  • 必要な画面
  • データの種類

非機能要件:

  • レスポンシブ対応
  • パフォーマンス
  • アクセシビリティ

2-2. ワイヤーフレーム

簡単な画面設計図を作成します。

ツール:

例: ブログサイトの画面構成

┌─────────────────────────────┐
│  Header (ナビゲーション)     │
├─────────────────────────────┤
│                             │
│  Hero Section               │
│  - タイトル                  │
│  - サブタイトル               │
│                             │
├─────────────────────────────┤
│  記事一覧                    │
│  ┌─────┐ ┌─────┐ ┌─────┐  │
│  │Card │ │Card │ │Card │  │
│  └─────┘ └─────┘ └─────┘  │
├─────────────────────────────┤
│  Footer                     │
└─────────────────────────────┘

2-3. データ設計

必要なデータ構造を定義します。

// 例: ブログの型定義
interface Post {
  id: string;
  title: string;
  content: string;
  excerpt: string;
  coverImage: string;
  date: string;
  author: {
    name: string;
    avatar: string;
  };
  tags: string[];
}

interface Category {
  id: string;
  name: string;
  slug: string;
}

3. プロジェクト構成

3-1. ディレクトリ構造(推奨)

project/
├── src/
│   ├── app/                  # Next.js App Router
│   │   ├── layout.tsx
│   │   ├── page.tsx
│   │   ├── blog/
│   │   │   ├── page.tsx
│   │   │   └── [slug]/
│   │   │       └── page.tsx
│   │   └── api/
│   │       └── posts/
│   │           └── route.ts
│   ├── components/           # UIコンポーネント
│   │   ├── ui/              # 汎用UIパーツ
│   │   │   ├── Button.tsx
│   │   │   ├── Card.tsx
│   │   │   └── Input.tsx
│   │   ├── layout/          # レイアウト
│   │   │   ├── Header.tsx
│   │   │   ├── Footer.tsx
│   │   │   └── Navigation.tsx
│   │   └── features/        # 機能別
│   │       ├── blog/
│   │       └── auth/
│   ├── lib/                 # ユーティリティ
│   │   ├── api.ts
│   │   └── utils.ts
│   ├── hooks/               # カスタムフック
│   │   ├── useAuth.ts
│   │   └── usePosts.ts
│   ├── types/               # 型定義
│   │   └── index.ts
│   └── styles/              # グローバルスタイル
│       └── globals.css
├── public/                  # 静的ファイル
│   ├── images/
│   └── fonts/
├── .env.local               # 環境変数
├── next.config.js
├── tailwind.config.ts
├── tsconfig.json
└── package.json

4. 実装のベストプラクティス

4-1. コンポーネント設計

Single Responsibility(単一責任):

// ❌ 悪い例: 1つのコンポーネントで全部やる
function BlogPage() {
  // データ取得、状態管理、UI、全部ここ
}

// ✅ 良い例: 責任を分離
function BlogPage() {
  const { posts } = usePosts(); // データ取得
  return <PostList posts={posts} />; // UIは別コンポーネント
}

Props Drilling を避ける:

// Context APIを使う
import { createContext, useContext } from 'react';

const ThemeContext = createContext('light');

export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

export function useTheme() {
  return useContext(ThemeContext);
}

4-2. 状態管理

ローカル状態 vs グローバル状態:

// ローカル: 1つのコンポーネント内のみで使う
const [open, setOpen] = useState(false);

// グローバル: 複数のコンポーネントで共有
// Context API、Zustand、Jotaiなどを使用

4-3. エラーハンドリング

// app/error.tsx
'use client'

export default function Error({
  error,
  reset,
}: {
  error: Error;
  reset: () => void;
}) {
  return (
    <div className="min-h-screen flex items-center justify-center">
      <div className="text-center">
        <h2 className="text-2xl font-bold mb-4">エラーが発生しました</h2>
        <p className="text-gray-600 mb-6">{error.message}</p>
        <button
          onClick={reset}
          className="px-6 py-2 bg-blue-500 text-white rounded"
        >
          再試行
        </button>
      </div>
    </div>
  );
}

// app/loading.tsx
export default function Loading() {
  return (
    <div className="min-h-screen flex items-center justify-center">
      <div className="animate-spin h-12 w-12 border-4 border-blue-500 border-t-transparent rounded-full" />
    </div>
  );
}

5. テストとデバッグ

5-1. チェックリスト

機能テスト:

  • ✅ 全ページが正しく表示される
  • ✅ リンクが正しく動作する
  • ✅ フォームの送信が正しく動作する
  • ✅ エラーハンドリングが動作する

レスポンシブテスト:

  • ✅ モバイル(375px)
  • ✅ タブレット(768px)
  • ✅ デスクトップ(1024px以上)

ブラウザテスト:

  • ✅ Chrome
  • ✅ Safari
  • ✅ Firefox
  • ✅ Edge

パフォーマンス:

  • ✅ Lighthouse スコア 90以上
  • ✅ 画像最適化
  • ✅ 不要なJavaScriptの削除

5-2. デバッグツール

// 開発環境でのみログ出力
if (process.env.NODE_ENV === 'development') {
  console.log('Debug:', data);
}

// React Developer Tools
// Chrome拡張機能をインストール

6. 総合制作プロジェクト例

6-1. 個人ブログサイト

機能:

  • 記事の一覧表示
  • 記事の詳細表示
  • カテゴリー別表示
  • タグ検索
  • お問い合わせフォーム

技術スタック:

  • Next.js 14 (App Router)
  • TypeScript
  • Tailwind CSS
  • Markdown (記事管理)

実装の流れ:

  1. プロジェクト作成
npx create-next-app@latest my-blog
cd my-blog
npm run dev
  1. 記事データの管理
# posts/first-post.md
---
title: "最初の投稿"
date: "2025-01-01"
tags: ["tech", "nextjs"]
---

記事の本文...
  1. 記事の読み込み
// lib/posts.ts
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';

export function getAllPosts() {
  const postsDirectory = path.join(process.cwd(), 'posts');
  const filenames = fs.readdirSync(postsDirectory);

  return filenames.map((filename) => {
    const filePath = path.join(postsDirectory, filename);
    const fileContents = fs.readFileSync(filePath, 'utf8');
    const { data, content } = matter(fileContents);

    return {
      slug: filename.replace('.md', ''),
      ...data,
      content
    };
  });
}
  1. 一覧ページ
// app/blog/page.tsx
import { getAllPosts } from '@/lib/posts';
import { PostCard } from '@/components/PostCard';

export default function BlogPage() {
  const posts = getAllPosts();

  return (
    <div className="container mx-auto px-4 py-12">
      <h1 className="text-4xl font-bold mb-8">ブログ</h1>
      <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
        {posts.map((post) => (
          <PostCard key={post.slug} post={post} />
        ))}
      </div>
    </div>
  );
}

7. 改善サイクル

7-1. フィードバック収集

  • 友人・家族に使ってもらう
  • SNSで公開してフィードバックをもらう
  • Google Analyticsでユーザー行動を分析

7-2. 継続的改善

  1. 問題点の特定
  2. 優先順位付け
  3. 実装
  4. テスト
  5. デプロイ

総合課題

課題: 自分だけのWebサイトを作ろう

以下のいずれかを選んで、完成させてください:

  1. ポートフォリオサイト

    • 自己紹介
    • プロジェクト紹介
    • スキル一覧
    • お問い合わせフォーム
  2. 個人ブログ

    • 記事の一覧・詳細
    • カテゴリー分類
    • 検索機能
    • RSS配信
  3. 趣味のWebアプリ

    • 読書記録
    • 映画レビュー
    • レシピ管理

要件:

  • ✅ レスポンシブデザイン
  • ✅ SEO対策
  • ✅ Vercelにデプロイ
  • ✅ GitHubで公開
  • ✅ README.mdに説明を記載

まとめ

このコース全体で学んだこと:

  • 第1章: 環境構築
  • 第2章: HTML & CSS
  • 第3章: JavaScript基礎
  • 第4章: TypeScript
  • 第5章: React基礎
  • 第6章: Next.js
  • 第7章: UX向上
  • 第8章: 公開と運用
  • 第9章: 総合制作

おめでとうございます!あなたはWebフロントエンド開発の基礎から応用まで学び、実際にWebサイトを公開できるようになりました。


次のステップ

さらに学ぶべきこと

フロントエンド:

  • アニメーションライブラリ(Framer Motion)
  • 状態管理(Zustand, Jotai)
  • テスト(Jest, React Testing Library)

バックエンド:

  • Next.js API Routes
  • データベース(Prisma + PostgreSQL)
  • 認証(NextAuth.js)

DevOps:

  • Docker
  • CI/CD
  • モニタリング

この章で習得すべきスキル

学習を完了したら、以下の項目をチェックしてください:

プロジェクト計画

  • チュートリアルと実践の違いを理解している
  • MVP思考でプロジェクトを計画できる
  • プロジェクトのスコープを定義できる
  • 要件を明確化できる

設計スキル

  • ワイヤーフレームを描ける(紙でもツールでも)
  • データ構造を設計できる
  • TypeScriptの型定義から設計を始められる
  • コンポーネント構成を考えられる

アーキテクチャ

  • Atomic Designの概念を理解している
  • コンポーネントを適切に分割できる
  • 状態管理の設計ができる
  • Props Drilling問題を理解し、対処できる

開発プロセス

  • ウォーターフォールとアジャイルの違いを理解している
  • Git のブランチ戦略を理解している
  • コミットメッセージを適切に書ける

テストとデバッグ

  • テストの重要性を理解している
  • console.logで効果的にデバッグできる
  • ブラウザの開発者ツールを使いこなせる
  • エラーメッセージから問題を特定できる

コード品質

  • 単一責任の原則を理解している
  • コードの可読性を意識できる
  • 再利用可能なコンポーネントを作成できる
  • 適切な命名ができる

実践スキル

  • ゼロから個人プロジェクトを立ち上げられる
  • プロジェクト構成を自分で決められる
  • 問題を分解して解決できる
  • 完成したプロジェクトをデプロイできる

継続的改善

  • フィードバックを収集できる
  • 優先順位をつけて改善できる
  • パフォーマンスを測定できる
  • アクセシビリティを考慮できる

次のステップへの準備

  • さらに学ぶべき技術を特定できる
  • 自分の強みと弱みを理解している
  • 継続的な学習の重要性を理解している

参考リンク


コミュニティ


おつかれさまでした!これからも学び続けて、素晴らしいWebサイトを作っていきましょう!