Hayami Kaito Web
~/tech

Windows 11 と VS Code で Next.js の Web ページを作る(launch.json でデバッグまで)

published

Windows 11 と VS Code を使って、Next.js で簡単な Web ページを作る手順を説明します。プロジェクトの作成から、ページの追加、クリックで数が増えるボタンの実装までを順に進め、最後に .vscode/launch.json を用意して F5 キー 1 つで開発サーバーの起動とブラウザでの動作確認、ブレークポイントでの停止ができるようにします。

この記事で作るもの

  • トップページ(/): 見出し・リスト・クリック回数を数えるボタン
  • 自己紹介ページ(/about): トップページとリンクで行き来する
  • .vscode/launch.json: サーバー側・ブラウザ側のコードをデバッグする設定

環境

項目バージョン
OSWindows 11
エディターVisual Studio Code
ブラウザーMicrosoft Edge(Windows 11 に標準で入っているもの)
Node.js24.x(LTS)
pnpm12.x
Next.js16.4.2
React19.3.0

Next.js 16 の動作には Node.js 20.9 以上が必要です。pnpm 12 を npm 経由でインストールするには Node.js 22.13 以上が必要なので、LTS 版(24.x)を入れておけば両方を満たせます。

手順

1. Node.js をインストールする

Node.js の公式サイトから LTS 版の Windows Installer(.msi) をダウンロードし、画面の指示に従ってインストールします。

インストールが終わったら、ターミナル(PowerShell)を新しく開き、バージョンが表示されることを確認します。

node -v

2. pnpm をインストールする

パッケージマネージャーには pnpm を使います。pnpm の公式ドキュメントでは、Windows では npm を使ったインストールが推奨されています(スタンドアロンのスクリプトだと Windows Defender に実行ファイルをブロックされることがあるため)。

npx get-pnpm

ターミナルを開き直して、バージョンが表示されれば完了です。

pnpm -v

3. VS Code を準備する

VS Code をインストールしていなければ、インストールしておきます。デバッグに必要な JavaScript デバッガーは VS Code に最初から入っているので、拡張機能を追加しなくてもこの記事の手順は進められます。

4. Next.js のプロジェクトを作る

作業用のフォルダー(例: C:\dev)に移動して、create-next-app でプロジェクトを作ります。my-app の部分がフォルダー名になります。

cd <作業用のフォルダー>
pnpm create next-app@latest my-app --yes

--yes を付けると質問を飛ばし、推奨の設定(TypeScript・ESLint・Tailwind CSS・App Router など)でプロジェクトが作られます。作ったフォルダーを VS Code で開きます。

cd my-app
code .

主なファイルは次のとおりです。

my-app/
  app/
    layout.tsx    ← すべてのページに共通の外枠(<html> や <body>)
    page.tsx      ← トップページ(/)
    globals.css   ← 全体のスタイル(Tailwind CSS の読み込み)
  public/         ← 画像などをそのまま配信するフォルダー
  next.config.ts  ← Next.js の設定
  package.json

App Router では、app/ の中のフォルダー構成がそのまま URL になり、各フォルダーの page.tsx がそのページの中身になります。

5. 開発サーバーで表示を確認する

VS Code のターミナル(日本語キーボードなら Ctrl+@ で開けます)で開発サーバーを起動します。

pnpm dev

ブラウザで http://localhost:3000 を開くと、Next.js の初期ページが表示されます。開発サーバーは Ctrl+C で止められます。

6. トップページを書き換える

app/page.tsx の中身をすべて次のコードに置き換えます。

app/page.tsx:

import Link from "next/link";
import Counter from "./components/Counter";

const skills = ["HTML", "CSS", "TypeScript", "React"];

export default function Home() {
  const message = `学習中の技術は ${skills.length} 個です`;

  return (
    <main className="mx-auto flex max-w-2xl flex-col gap-6 px-6 py-16">
      <h1 className="text-3xl font-bold">はじめての Next.js</h1>
      <p>{message}</p>
      <ul className="list-disc pl-6">
        {skills.map((skill) => (
          <li key={skill}>{skill}</li>
        ))}
      </ul>
      <Counter />
      <Link href="/about" className="text-blue-600 underline">
        自己紹介ページへ
      </Link>
    </main>
  );
}

className に書いているのは Tailwind CSS のクラスです(text-3xl で文字を大きく、font-bold で太字に、など)。

7. クリックで数が増えるボタンを作る

ボタンのように、ブラウザ上で状態(ここではクリック回数)を持つ部品は Client Component として作ります。ファイルの先頭に "use client"; を書くと Client Component になります。

app/components/Counter.tsx を新しく作ります。

app/components/Counter.tsx:

"use client";

import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);

  const handleClick = () => {
    setCount(count + 1);
  };

  return (
    <button
      type="button"
      onClick={handleClick}
      className="w-fit rounded bg-blue-600 px-4 py-2 text-white"
    >
      クリックした回数: {count}
    </button>
  );
}

"use client" を書いていないコンポーネントは Server Component で、サーバー側(開発時は開発サーバー、本番ではビルド時やリクエスト時)で HTML に変換されます。app/page.tsx は Server Component、Counter.tsx は Client Component です。この違いは、あとでデバッグするときに「どちらのデバッガーで止まるか」に関わってきます。

8. 2 つ目のページを追加する

app/about/page.tsx を作ると、/about というページが増えます。

app/about/page.tsx:

import type { Metadata } from "next";
import Link from "next/link";

export const metadata: Metadata = {
  title: "自己紹介",
};

export default function About() {
  return (
    <main className="mx-auto flex max-w-2xl flex-col gap-6 px-6 py-16">
      <h1 className="text-3xl font-bold">自己紹介</h1>
      <p>Next.js で Web ページを作っています。</p>
      <Link href="/" className="text-blue-600 underline">
        トップページへ戻る
      </Link>
    </main>
  );
}

metadata を書き出すと、そのページの <title> などを設定できます。ページ間のリンクには <a> ではなく next/link の <Link> を使うと、ページ全体を読み込み直さずに切り替わります。

9. サイト全体のタイトルと言語を変える

app/layout.tsx の metadata と <html> の lang を日本語のページ向けに変えます。

app/layout.tsx:

 export const metadata: Metadata = {
-  title: "Create Next App",
-  description: "Generated by create next app",
+  title: "はじめての Next.js",
+  description: "Next.js で作った練習用の Web ページ",
 };

 export default function RootLayout({ children }: LayoutProps<"/">) {
   return (
     <html
-      lang="en"
+      lang="ja"
       className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
     >

pnpm dev を起動したままなら、保存するたびにブラウザの表示が自動で更新されます。http://localhost:3000 でボタンを押すと数が増え、リンクで /about と行き来できれば完成です。

launch.json でデバッグできるようにする

ここからは、F5 キーで開発サーバーの起動からブラウザでの確認までを済ませ、ブレークポイントでコードを止められるようにします。

1. launch.json を作る

プロジェクトのルートに .vscode フォルダーを作り、その中に launch.json を作ります。内容は Next.js 公式のデバッグガイドの設定をもとに、Windows 11 に標準で入っている Edge を使い、コマンドを pnpm に合わせたものです。

.vscode/launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Next.js: debug server-side",
      "type": "node-terminal",
      "request": "launch",
      "command": "pnpm dev --inspect"
    },
    {
      "name": "Next.js: debug client-side",
      "type": "msedge",
      "request": "launch",
      "url": "http://localhost:3000"
    },
    {
      "name": "Next.js: debug full stack",
      "type": "node",
      "request": "launch",
      "program": "${workspaceFolder}/node_modules/next/dist/bin/next",
      "runtimeArgs": ["--inspect"],
      "skipFiles": ["<node_internals>/**"],
      "serverReadyAction": {
        "action": "debugWithEdge",
        "killOnServerStop": true,
        "pattern": "- Local:.+(https?://.+)",
        "uriFormat": "%s",
        "webRoot": "${workspaceFolder}"
      }
    }
  ]
}

3 つの構成の違いは次のとおりです。

構成名何をするか止められるコード
Next.js: debug server-sideターミナルで pnpm dev --inspect を実行し、開発サーバーにデバッガーをつなぐServer Component(app/page.tsx など)
Next.js: debug client-sideEdge を起動して http://localhost:3000 を開き、ブラウザにデバッガーをつなぐ。開発サーバーは別に起動しておくClient Component(Counter.tsx など)
Next.js: debug full stack開発サーバーを起動し、準備ができたら Edge を自動で開いて両方にデバッガーをつなぐ両方

普段の動作確認には、**F5 キー 1 つで全部そろう「debug full stack」**が便利です。開発サーバーが - Local: http://localhost:3000 と表示したのを serverReadyAction の pattern が見つけ、その URL を Edge で開く仕組みです。

Chrome を使いたい場合は、"type": "msedge" を "chrome" に、"debugWithEdge" を "debugWithChrome" に変えます。

2. F5 キーで起動する

  1. 左のアクティビティバーから「実行とデバッグ」を開く(Ctrl+Shift+D)
  2. 上部のプルダウンで Next.js: debug full stack を選ぶ
  3. F5 キーを押す

開発サーバーが起動し、少し待つと Edge が http://localhost:3000 を開いた状態で立ち上がります。止めるときは、上部のデバッグツールバーの停止ボタン(Shift+F5)を押します。killOnServerStop を true にしているので、開発サーバーを止めると Edge 側のデバッグも一緒に終わります。

3. ブレークポイントで止めてみる

行番号の左をクリックすると赤い丸(ブレークポイント)が付きます。次の 2 か所に付けてみましょう。

ファイル行止まるタイミング
app/page.tsxconst message = ... の行ページを開いた・再読み込みしたとき(サーバー側で HTML を作るとき)
app/components/Counter.tsxsetCount(count + 1); の行ブラウザでボタンを押したとき

ブレークポイントで止まると、左の「変数」パネルで skills や count の値を確認できます。F10 で 1 行ずつ進め、F5 で次のブレークポイントまで実行を続けます。

page.tsx は Server Component なので、ブラウザではなく開発サーバー(Node.js)側で止まります。一方 Counter.tsx のクリック処理はブラウザで動くので、Edge 側のデバッガーで止まります。どちらで止まるかを見ると、コードがどこで実行されているのかが分かります。

ハマりどころ

  • node や pnpm が「認識されません」と出る: インストール前に開いていたターミナルや VS Code には、新しい PATH が反映されていません。ターミナルと VS Code をいったん閉じて開き直します
  • PowerShell で「スクリプトの実行が無効」と出て pnpm が動かない: PowerShell の実行ポリシーで .ps1 の実行が止められている状態です。自分のユーザーだけ許可するなら、Set-ExecutionPolicy -Scope CurrentUser RemoteSigned を実行します
  • ポート 3000 が使われていて別のポートで起動した: 開発サーバーがすでに動いていると、3001 など別のポートで起動します。「debug full stack」は表示された URL を開くのでそのまま使えますが、「debug client-side」は url が 3000 固定なので、先に起動している開発サーバーを止めます
  • 保存してから表示が変わるまで遅い: Next.js の公式ドキュメントでは、Windows Defender がファイルの読み込みを 1 つずつ検査するため、pnpm dev の更新(Fast Refresh)が遅くなることがあると注意されています

まとめ

  • pnpm create next-app@latest my-app --yes でプロジェクトを作り、pnpm dev で確認しながら作れる
  • App Router では app/<フォルダー>/page.tsx がそのままページになる
  • 状態を持つ部品は "use client" を付けた Client Component にする
  • .vscode/launch.json に「debug full stack」を用意すれば、F5 キーで開発サーバーとブラウザの起動、サーバー側・ブラウザ側の両方のデバッグまでまとめてできる

参考