既存のReactプロジェクトにNext.jsを導入する方法

## アジェンダ
既存のReactプロジェクト(create-react-appで作成したプロジェクト)にNext.jsを導入する方法についてまとめます。
Reactプロジェクトが既に存在しているので、追加でパッケージをインストールしていく方法でNext.jsを導入していきます。

## 導入手順
### 1. Next.jsのインストール:
まずは、下記コマンドを実行し、パッケージをインストールしていきます。
```bash
npm install next react react-dom
```

### 2. プロジェクトの構成変更:
続いて、`pages`ディレクトリを作成し、既存のReactコンポーネントを移動します。例えば、`src/index.js`を`pages/index.js`に移動します。
これは、Next.jsが`pages`ディレクトリ内のファイルをルーティングするためです。

### 3. package.jsonにスクリプトを追加:
Next.jsを使用するために、package.jsonにいくつかのスクリプトを追加する必要があります。これにより、開発サーバーの起動やビルド、アプリの起動が簡単になります。

```json
"scripts": {
  "dev": "next dev",
  "build": "next build",
  "start": "next start"
}
```

### 4. カスタムの`_app.js`と`_document.js`と`_error.js`の作成（必要に応じて）:
#### `_app.js`の場合
例えば、グローバルCSSを適用する場合、`カスタム<App>`つまり`_app.tsx`だけにしかできない使用にNext.jsではなっているので、`app.tsx`では`カスタム<App>`だと認識できず、`app.tsx`でグローバルなCSSが読み込まれると`カスタム<App>`以外でグローバルなCSSを読み込んでいると解釈されてしまいます。

`_app.js`は全ページ共通のレイアウトやスタイルを設定するために使用されます。
```tsx:pages/_app.js
import '../styles/globals.css'

function MyApp({ Component, pageProps }) {
    return <Component {...pageProps} />
}

export default MyApp
```
#### `_document.js`の場合
_document.jsはHTMLドキュメント全体をカスタマイズするために使用されます。
```tsx:pages/_document.js
import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
    return (
        <Html>
           <Head />
           <body>
             <Main />
             <NextScript />
           </body>
         </Html>
    )
}
```

#### `_error.js`の場合
_error.jsはカスタムエラーページを作成するために使用されます。例えば、404エラーページをカスタマイズする場合、以下のようにします。
```tsx:pages/_error.js
function Error({ statusCode }) {
    return (
        <p>
            {statusCode
                ? `An error ${statusCode} occurred on server`
                : 'An error occurred on client'}
        </p>
    )
}

Error.getInitialProps = ({ res, err }) => {
    const statusCode = res ? res.statusCode : err ? err.statusCode : 404
    return { statusCode }
}

export default Error
```

### 5. CSSとスタイルの調整:
`pages`ディレクトリ内で使用されるCSSを調整します。Next.jsはCSSモジュールをサポートしているので、ファイル名を`filename.module.css`とすることでCSSモジュールを使用できます。

### 例
以下は簡単な移行の例です。元のReactプロジェクトが以下のような構造を持っているとします。

```
my-react-app/
├── src/
│   ├── App.js
│   └── index.js
└── package.json
```

これをNext.jsに移行すると次のような構造になります。

```
my-next-app/
├── pages/
│   ├── index.js
│   └── _app.js
├── styles/
│   └── globals.css
└── package.json
```

元のApp.jsの内容をpages/index.jsに移動し、必要に応じて_app.jsを設定することで移行が完了します。

### 6.React RouterからNext.jsのルーティングへ移行:
React Routerを使用している場合、Next.jsのルーティングに移行する必要があります。例えば、以下のようにReact Routerの設定を行っている場合:
```tsx:src/App.js
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Home from './Home';
import About from './About';

function App() {
    return (
        <Router>
            <Switch>
                <Route path="/" exact component={Home} />
                <Route path="/about" component={About} />
            </Switch>
        </Router>
    );
}

export default App;
```

これをNext.jsに移行すると、pagesディレクトリに各コンポーネントを配置することで同様のルーティングが実現できます。

```tsx:pages/index.js
import Home from '../components/Home';

export default function Index() {
    return <Home />;
}

// pages/about.js
import About from '../components/About';

export default function AboutPage() {
    return <About />;
}
```
以上で、既存のReactプロジェクトにNext.jsを導入する基本的な手順が完了です。

## 参考
- [Next.jsの基本的な使い方(個人学習の備忘録) #初心者 - Qiita](https://qiita.com/marl0401/items/4a3f0133a4de3712ad3c)
- [Next.jsのマニュアル設定](https://zenn.dev/hrkmtsmt/scraps/f3125a7b516e54)
- [はじめに | Next.js](https://nextjs-ja-translation-docs.vercel.app/docs/getting-started)