React、npm start時、node_modulesでModule not foundが発生した時に解決した方法（create-react-app）

今回はReactのプロジェクトで、Reactのバージョンを17 → 18 へバージョンアップ対応を行っていた時に発生した問題でした。
設定ファイルをejectする方法もありますが、非推奨なのと、後戻りできない可能性があるので
今回は設定ファイルを上書きする方法です。

<h2>結論</h2>

手動でパッケージをインストール
webpack.config.jsをオーバーライドして、使用できるように設定する

<h2>エラーが発生する前にやったこと</h2>

1. Reactのver17からver18へバージョンアップ
2. react-scriptsのバージョンを4系から5系へバージョンアップ
3. その他依存するパッケージをバージョンアップ

おそらく関係しているのは2のreact-scripts？
react-scriptsが、内部的にwebpackやbabelを使って開発用サーバー起動やビルド等をよしなにやってくれているようです。

<h2>エラーの原因</h2>

- webpackのver4からver5に変わったタイミングで破壊的変更が入った
簡単に言うと今まで標準搭載されていたものがなくなったようです...
Webpack 5では、デフォルトでNode.jsのコアモジュールのポリフィルが含まれなくなったため、これらのエラーが発生しているみたいです。
ポリフィル：[Web開発で聞くポリフィル(polyfill)とは？](https://web-engineer-wiki.com/javascript/polyfill/)

- 今回のエラーメッセージ
```
ERROR in ./node_modules/labelmake/dist/labelmake.min.js 3:98-113
Module not found: Error: Can't resolve 'zlib' in 'パス/ファイル名'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "zlib": require.resolve("browserify-zlib") }'
	- install 'browserify-zlib'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "zlib": false }
```
インストールするか、使用しないことを明示的に設定しろと言っています。
→設定するファイルは命名規則ではwebpack.config.jsとなっています

<h2>詰まったポイント</h2>

前述した通り設定ファイルを編集するよう促されますが、ここで問題が発生します。
「webpack.config.js」がありません...
create-react-appでReactのプロジェクトを立ち上げると、webpackの設定ファイルが隠蔽されるようです。
ちなみにwebpackの設定ファイルは以下のパスにあります。
```
/node_modules/react-scripts/config/webpack.config.js
```
ネットで検索するとwebpack.config.jsを編集するという対応法が数多く見つかりますが
npm installコマンドによって生成されるnode_modules配下を編集することは出来ません
また、パッケージをインストールするだけでもエラーは解決しません
※モジュールによっては解決するものもあるようです

<h2>対応</h2>

今回のケースでは、パッケージをインストールし、
webpack.config.jsをオーバーライドすることで解決しました。

<h3>インストール</h3>

まずはエラーメッセージにあるパッケージをインストール
今回の場合だとエラーメッセージに「install 'browserify-zlib'」と表示されているので、インストールします。
```
# yarnの場合
yarn add browserify-zlib
# npmの場合
npm i browserify-zlib
```

<h3>設定ファイルのオーバーライド</h3>
<h5>パッケージのインストール</h5>

設定ファイルのオーバーライドには必要なパッケージが2つ
開発環境のみで使用するパッケージのためdevオプションを付与しています。
- react-app-rewired
- customize-cra
```
# yarnの場合
yarn add react-app-rewired customize-cra --dev
# npmの場合
npm install react-app-rewired customize-cra --save-dev
```

<h5>package.jsonを修正</h5>

```diff
# 修正前
-    "start": "react-scripts start",
-    "build": "react-scripts build",
-    "test": "react-scripts test",
# 修正後
+    "start": "react-app-rewired start",
+    "build": "react-app-rewired build",
+    "test": "react-app-rewired test",
```

<h5>ファイルを作成</h5>

プロジェクトのルートに、設定ファイルをオーバーライドするための構成ファイルを作成します。
package.jsonと同じ階層になるかと思います。
```
# ファイル名
config-overrides.js
```
オーバーライドする設定を記述していきます。
```javascript:config-overrides.js
module.exports = function override(config, env) {
    config.resolve.alias = {
      ...config.resolve.alias,
      zlib: require.resolve('browserify-zlib')
      // 他にもあれば続けて記述
      // 以下は例
      // stream: require.resolve('stream-browserify'),
      // assert: require.resolve('assert/'),
      // buffer: require.resolve('buffer/'),
      // util: require.resolve('util/')
    };
    return config;
  };
```

以上で対応は完了です。
パッケージの公式ドキュメントはコチラ：[react-app-rewired](https://github.com/timarney/react-app-rewired)

<h2>最後に</h2>

webpackの設定ファイル（webpack.config.js）が存在しない場合は
同様の手順で設定ファイルを上書きすることが可能です。

そもそもcreate-react-appは使用するなという意見が多く見受けられるので、
新規でプロジェクトを立ち上げるなら避けた方が良さそう...
※柔軟な設定ができないようです

web開発の知見が浅いため、誤っている点があるかもしれません。
不手際があれば指摘いただけると嬉しく思います。