【React】Webpackの設定で3種類のエラーが出たから原因と解決方法をここに記す

# 目次
[1.動作環境](#1-動作環境)
[2.バンドルしたファイル](#2-バンドルしたファイル)
[3.バンドル成功時のWebpackの設定](#3-バンドル成功時のwebpackの設定)
[4.上記のコードになるまでに出たエラー文と原因と解決方法](#4-上記のコードになるまでに出たエラー文と原因と解決方法)


# 1. 動作環境
Windows10
React 18.1.0
Webpack5
npm 8.5.5 (←2022年3月22日に公開されたバージョン)

# 2. バンドルしたファイル
今回Webpackで<b>index.jsを起点に2つのcssファイル、4つのjsファイルを辿って計6つのファイルをバンドル</b>しました。

![1654162588247.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1311883/c35d441c-4255-33e2-721c-2e8eee5ca7a1.jpeg)



# 3. バンドル成功時のWebpackの設定
```webpack.config.js
module.exports = {
    mode: "production",
    entry: "./src/index.js",
    output: {
        path: `${__dirname}/dist`,
        filename: "bandle.js"
    },

    module: {
        rules: [
            // test = loaderを使う特定の拡張子を指定
            // use = testで指定した拡張子にloaderを使いwebpackが読み込めるようにする
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"],
                //↑公式docによると、上記2つのloaderを追加すればCSSが読めるらしい
            },
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        //↓JSX構文を使ったjsファイルを読み込むためのpresetsを追加する
                        presets: [
                            '@babel/preset-react' //ここにpresetを追加
                        ],
                    }
                },
            },
        ],
    }
}
```

# 4. 上記のコードになるまでに出たエラー文と原因と解決方法
合計で3種類のエラーが出ました。

## ①Module parse failed: Unexpected token (9:2)<font color="Red">You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. </font>See https?//webpack.js.org/concepts#loaders

### 原因
これはWebpackが扱えないファイルの拡張子が含まれている場合に出るエラーのようでした。
Webpackはデフォルトではjsファイルだけ読み取れるはずなので、エラー文にある"this file type"が指しているファイルはcssである。

### 解決策
CSSファイルを読み取れるようにcss用のloaderを使う。
それが↑のコードのここの部分
```webpack.config.js
    module: {
        rules: [
            // test = loaderを使う特定の拡張子を指定 (正規表現で記述。css以外なら「css」の部分を指定したい拡張子名に変えればオッケーだと思います)
            // use = testで指定した拡張子にloaderを使いwebpackが読み込めるようにする
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"],
                //↑公式docによると、上記2つのloaderを追加すればCSSが読めるらしい
            },
```

## ②SyntaxError: C: ../src/App.js:<font color="Red"> Support for the experimental syntax 'jsx' isn't currently enabled </font>
### 原因
App.js内にあるjsx構文を読み取れませんというエラー。
<b>loader: babel-loaderだけではjsファイルは読み取れても、そのjsファイル内のjsx構文は読み取れないらしい。</b>（なんでや！！）

### 解決策
presetを追加してbabel-loaderでjsx構文を読み取れるように強化する
強化するコードがコレ↓
```webpack.config.js
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        //↓JSX構文を使ったjsファイルを読み込むためのpresetsを追加する
                        presets: [
                            '@babel/preset-react' //ここにpresetを追加
                        ],
                    }
                },
            },
```
presetはloaderの拡張プラグインの詰め合わせキットという認識であってますかね？？？（わかる方コメント欄でお願いします）

## ③Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.configuration.module.rules[1] should be one of these: ["..." | object { assert?, compiler?, （以下略）}, ...]<br>-> A rule.Details:<font color="Red">configuration.module.rules[1].use.loader should be a non-empty string.</font>-> A loader request.

### 原因
<font color="Red">configuration.module.rules[1].use.loader should be a non-empty string.</font>と書いてある通り、「loaderは空ではない文字列にしなさい」とのこと。
このエラーが出たときは、jsファイルに対するloaderを複数指定していました。
エラーが出たときのコードがこちら
```webpack.config.js
            {
              test: /\.js$/,
              use:{
                loader: ["babel-loader","react-markdown-loader"],  //←ここでbabel-loader以外のloaderを配列にしていた
                options: {
                    presets: ['@babel/preset-env', '@babel/preset-react'],
                    plugins: ['@babel/plugin-syntax-jsx']  //←これは@babel/preset-reactに含まれているpluginなので不要
                }
                },
            },
```
### 解決
解決したコードがこれ
loaderを一つの文字列にしました。エラーには関係ないけど不要なpluginも削除
```webpack.config.js
            {
                test: /\.js$/,
                use: {
                    loader: 'babel-loader',  //react-markdown-loaderを削除して文字列に。
                    options: {
                        presets: [ '@babel/preset-react' ],
                        // エラーには関係ないが不要なpluginを削除
                    }
                },
            },
```
不要（？）なreact-markdown-loaderを消してちゃんと文字列にしたってやりましたわ。


:::note warn
謎が謎を呼んだ
確かにエラーは改善したが、なぜjsのloaderは配列ではダメなのにcssのloaderは["style-loader", "css-loader"]の二つをuseしてもいいのか。（なんでや！！）