🐳

VSCode DevContainerでNext.js + TypeScript + Tailwind CSS開発環を作る🐳

2024/11/25に公開

DevContainerでNext.js開発環境を作る

はじめに

開発環境の構築は、チーム開発において重要かつ面倒な課題です。「自分の環境では動くのに...」という状況を避けるため、DevContainerを使用して統一された開発環境を構築する方法を紹介します。

ソースコードはgithubに載せてます

DevContainerとは?

DevContainerは、VSCodeの機能で、Dockerコンテナ内に完全な開発環境を構築できます。これにより:

  • チーム全員が同じ環境で開発可能
  • 新メンバーの環境構築が容易
  • ホストマシンを汚さない
  • プロジェクトごとに独立した環境を維持

環境構築手順

1. 前提条件

  • Docker Desktop (windowsの場合はWSL2にdockerを入れるのがおすすめ)
  • Visual Studio Code
  • Dev Containers拡張機能

2. DevContainer設定の追加

.devcontainerディレクトリを作成し、必要なファイルを追加します:

mkdir .devcontainer
cd .devcontainer

devcontainer.json:

{
  "name": "Next.js Project",
  "build": {
    "dockerfile": "Dockerfile",
    "context": ".."
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "bradlc.vscode-tailwindcss",
        "formulahendry.auto-rename-tag",
        "csstools.postcss",
        "ms-vscode.vscode-typescript-next"
      ],
      "settings": {
        "editor.formatOnSave": true,
        "[typescript]": {
          "editor.defaultFormatter": "vscode.typescript-language-features"
        },
        "[javascript]": {
          "editor.defaultFormatter": "vscode.typescript-language-features"
        },
        "[typescriptreact]": {
          "editor.defaultFormatter": "vscode.typescript-language-features"
        },
        "[javascriptreact]": {
          "editor.defaultFormatter": "vscode.typescript-language-features"
        },
        "[json]": {
          "editor.defaultFormatter": "vscode.json-language-features"
        },
        "[css]": {
          "editor.defaultFormatter": "vscode.css-language-features"
        },
        "editor.codeActionsOnSave": {
          "source.fixAll": "explicit"
        },
        "typescript.tsdk": "node_modules/typescript/lib"
      }
    }
  },
  "forwardPorts": [3000],
  "workspaceMount": "source=${localWorkspaceFolder}/my-project,target=/workspace,type=bind,consistency=cached",
  "workspaceFolder": "/workspace",
  "postCreateCommand": "npm install",
  "remoteUser": "node"
}

Dockerfile:

FROM node:20-slim

# 必要最小限のパッケージのみインストール
RUN apt-get update && apt-get install -y \
    git \
    && rm -rf /var/lib/apt/lists/*

# ワークスペースディレクトリを作成
WORKDIR /workspace

# タイムゾーンを設定
ENV TZ=Asia/Tokyo

3. DevContainerの起動

  1. VSCodeでプロジェクトを開く
  2. コマンドパレット(F1)から「Dev Containers: Reopen in Container」を選択
  3. コンテナのビルドとセットアップが完了するまで待機

プロジェクトのカスタマイズ

パッケージの追加

新しいパッケージを追加する場合:

npm install <package-name>

スタイリングのカスタマイズ

tailwind.config.tsでTailwind CSSの設定をカスタマイズ:

import type { Config } from 'tailwindcss'

const config: Config = {
  content: [
    './pages/**/*.{js,ts,jsx,tsx,mdx}',
    './components/**/*.{js,ts,jsx,tsx,mdx}',
    './app/**/*.{js,ts,jsx,tsx,mdx}',
  ],
  theme: {
    extend: {
      // カスタムテーマ設定
    },
  },
  plugins: [],
}
export default config

コンポーネントの追加

appディレクトリ内に新しいコンポーネントを作成:

// app/components/Button.tsx
export default function Button({ children }) {
  return (
    <button className="px-4 py-2 bg-blue-500 text-white rounded">
      {children}
    </button>
  );
}

ページの追加

App Routerを使用したページの追加:

// app/about/page.tsx
export default function About() {
  return (
    <div className="p-4">
      <h1>About Page</h1>
    </div>
  );
}

開発のベストプラクティス

1. TypeScriptの型チェック

  • 厳格な型チェックを有効化(tsconfig.json
{
  "compilerOptions": {
    "strict": true
  }
}

2. ESLintルールのカスタマイズ

.eslintrc.jsonでプロジェクト固有のルールを設定:

{
  "extends": "next/core-web-vitals",
  "rules": {
    // カスタムルール
  }
}

3. gitignoreの設定

.gitignoreに以下を追加:

node_modules
.next
.env*.local

トラブルシューティング

1. コンテナが起動しない場合

  • Dockerデーモンが起動しているか確認
  • ポート3000が使用されていないか確認
  • DevContainer拡張機能が最新か確認

2. npm installが失敗する場合

# キャッシュのクリア
rm -rf node_modules
rm package-lock.json
npm cache clean --force
npm install

3. ホットリロードが効かない場合

next.config.tsで設定を確認:

const config = {
  webpack: (config) => {
    config.watchOptions = {
      poll: 1000,
      aggregateTimeout: 300,
    }
    return config
  },
}

export default config

4. プロジェクト名の変更

プロジェクト名を変更する場合、以下の箇所を修正する必要があります:

  1. プロジェクトディレクトリ名の変更
# my-projectを新しい名前に変更
mv my-project new-project-name
  1. package.jsonの修正
{
  "name": "new-project-name",  // この行を変更
  ...
}
  1. package-lock.jsonの修正
{
  "name": "new-project-name",  // この行を変更
  ...
}
  1. .devcontainer/devcontainer.jsonの修正
{
  ...
  "workspaceMount": "source=${localWorkspaceFolder}/new-project-name,target=/workspace,type=bind,consistency=cached",  // この行を変更
  ...
}

これらの変更後、DevContainerを再ビルドする必要があります:

  1. VSCodeのコマンドパレット(F1)を開く
  2. 「Dev Containers: Rebuild Container」を選択

5. ポート番号の変更

デフォルトの3000番から別のポートに変更する場合、以下の手順で設定を変更します:

  1. package.jsonのdev scriptを修正
{
  "scripts": {
    "dev": "next dev -p 3001",  // ポート番号を変更
    "start": "next start -p 3001"  // プロダクション環境用のポートも変更
  }
}
  1. .devcontainer/devcontainer.jsonforwardPortsを修正
{
  ...
  "forwardPorts": [3001],  // この行を変更
  ...
}
  1. 必要に応じて、next.config.tsでポート設定を追加
import type { NextConfig } from 'next'

const config: NextConfig = {
  server: {
    port: 3001, // ポート番号を設定
  },
  // 他の設定...
}

export default config

これらの変更後:

  1. 開発サーバーを再起動
  2. 新しいURL(http://localhost:3001)でアクセス

注意点:

  • ポート番号を変更する場合、チーム内で競合しない番号を選択すること
  • CI/CD環境がある場合、関連する設定も更新が必要
  • 環境変数(.env)でポート番号を管理している場合は、そちらも更新

まとめ

DevContainerを使用することで:

  • 環境構築の手間を大幅に削減
  • チーム全体で統一された開発環境を維持
  • 新規メンバーの参加時のオンボーディングを効率化

これにより、開発者はコードの品質向上や機能開発に集中できます。

サンプルコード

この記事で紹介した設定ファイルとサンプルコードは、以下のGitHubリポジトリで公開しています:
dev-container_for_Nextjs

リポジトリの使い方:

# リポジトリのクローン
git clone https://github.com/chantakan/dev-container_for_Nextjs.git

# プロジェクトディレクトリに移動
cd dev-container_for_Nextjs

# VSCodeで開く
code .

ご質問やフィードバック、改善提案があれば、コメントでお知らせください。また、GitHubリポジトリへのIssueやPull Requestも歓迎します。

参考リンク


この記事で紹介した設定ファイルとサンプルコードは、GitHubリポジトリで公開してます。ご質問やフィードバックがありましたら、コメントでお知らせください。

Discussion