運用中アプリケーションのReactのバージョンを試しに最新にした時の、npmライブラリ変更とその解決法メモ

Reactのバージョンがv16.2.0なので、v16.8.4（2019/03/07現在）に上げてみたらどうなるんだろう？と思い、ローカルで試してみました。
reactだけでなく、全てのライブラリを最新にしちゃいました！

##まずは全ライブラリのバージョンを最新にしてみた

使用していたライブラリはこの後書きますが、アップデート後にビルドしたらやはりエラーが表示されました。

```shell
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/
```

```shell
ERROR in ./index.jsx
Module build failed (from /Users/…/app/node_modules/babel-loader/lib/index.js):
Error: Cannot find module '@babel/core'
babel-loader@8 requires Babel 7.x (the package '@babel/core'). If you'd like to use Babel 6.x ('babel-core'), you should install 'babel-loader@7'.
```

まず上のエラーを解消するのに、以下の記事を参考にさせて頂きました！
[Webpack 4を使ってみたらビルド時に[WARNING]が出たので](https://qiita.com/MasanoriIwakura/items/32f9be227adab21d7f87)

webpack.config.jsの中に、以下のような記述を加えます。
`development` または `production`を入れてあげれば良いようです。

```javascript
module.exports = {
  mode: 'development',
  entry: ...
  ...
}
```

下のエラーが厄介そう…。。
下の記事を参考に、babel6関連のライブラリを一掃し、babel7に買えちゃいます！

[Webpack 4：babel-loader のアップデートで起きたエラーを解決](https://qiita.com/oreo3@github/items/b383c57949e0f117cbea)


##変更したライブラリの一部

### 削除して新しく入れ直したもの

|  削除したライブラリ  |  代わりに導入したライブラリ  |
| ---- | ---- |
|  babel-core  |  @babel/core  |
|  babel-plugin-transform-runtime  |  @babel/plugin-transform-runtime  |
|  babel-preset-env  |  @babel/preset-env  |
|  babel-preset-react  |  @babel/preset-react  |
|  babel-preset-stage-1  |    |
|  babel-register  |  @babel/register  |
|  flow-typed / flowtype  |  @babel/preset-flow  |
|    |  @babel/plugin-proposal-class-properties  |


### バージョンアップしただけのライブラリ

|  ライブラリ名  |  前  |  後  |
| ---- | ---- | ---- |
|  react  |  16.2.0  |  16.8.4  |
|  react-dom  |  16.2.0  |  16.8.4  |
|  redux  |  3.7.2  |  4.0.1  |
|  webpack  |  3.10.0  |  4.29.6  |



##エラーの対処の仕方

### `webpack.optimize.CommonsChunkPlugin`でエラー

```shell
Error: webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.
```

このエラーが出ていた時は、
webpack.config.js該当箇所はこんな記述でした。

```javascript
new webpack.optimize.CommonsChunkPlugin({
  name: 'manifest',
  minChunks: Infinity
}),
```

こちらの記事を参考にして解決しました！上記の記述を削除して、下を追加しました。

[webpack 4 の optimization.splitChunks の使い方、使い所 〜廃止された CommonsChunkPlugin から移行する〜](https://qiita.com/soarflat/items/1b5aa7163c087a91877d)

```javascript
optimization: {
  splitChunks: {
    name: 'manifest',
    chunks: 'initial'
  }
},
```

##babel 7用にwebpack.config.jsを書き換える！

以下のようなエラーが表示されました。webpack.config.jsの記述を書き換える必要がありそうです。

```shell
Error: Requires Babel "^7.0.0-0", but was loaded with "6.26.0". If you are sure you have a compatible version of @babel/core, it is likely that something in your build process is loading the wrong version. Inspect the stack trace of this error to look for thefirst entry that doesn't mention "@babel/core" or "babel-core" to see what is calling Babel.
```

悪戦苦闘の末のコードなので、途中経過が書けません…！下に、以前のコードと解決後のコードを比較して書いていきます！
（※一部抜粋して書いてます。ご了承下さい！）

```javascript
module.exports = {
  /* 新規追加 */
  mode: 'development',
  ...
  /* 新規追加 */
  optimization: {
    splitChunks: {
      name: 'manifest',
      chunks: 'initial'
    }
  },
  ...
  module: {
    rules: [
      /* 以前までのコード */
      {
        test: /\.jsx?$/,
        include: path.resolve('src', 'app'),
        loaders: ['react-hot-loader/webpack', 'babel-loader']
      },
      /* 上記のコードを書き換えたのが下です！ */
      {
        test: /\.(jsx|js)$/,
        include: path.resolve('src', 'app'),
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-flow']
            }
          }
        ]
      }
  ...
}
```

（`exclude: /node_modules/`は書いた方が良いです！）


##.babelrcの書き換え

よくわからないけど、表示されたエラーがこちらです。.babelrcファイルの修正が必要でした！

```shell
TypeError: this.setDynamic is not a function
```

（上のエラーについては、こちらの記事を参考にして解消できました！
[Module build failed: TypeError: this.setDynamic is not a function #560](https://github.com/babel/babel-loader/issues/560)）


```json
{
  /* 以前までのコード */
  "presets": ["env", "react", "stage-1"],
  /* 常軌を新しく書き換えたコード */
  "presets": [
    [
      "@babel/preset-env", {
        "targets": {
          "node": "current"
        }
      }
    ],
    "@babel/preset-react"
  ],
  /* 以前までのコード */
  "plugins": [
    "transform-runtime",
    ...
  ],
  /* 常軌を新しく書き換えたコード */
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-transform-runtime",
    ...
  ]
}
```

##まだ始まったばかり！

まだ環境整えただけ！笑
ここから、v16.8で使えるようになったReact Hooksを導入してみたり、v17から消えるライフサイクルメソッドを書き換えてみたり、色々試してみようと思っています。


##余談

実は上記のエラー以外にも、凡ミスが理由で長いこと格闘しちゃってました。。😭
webpack.config.jsやコンポーネント内で使っている様子もないライブラリを見つけたので、
「削除しても良さそう…（？）」（大丈夫、別にローカルだし…✌️）と思い、２つくらいremoveしました。
ところが…！cssフレームとして使用していた外部ライブラリに必須だったようで、ググっても辿り着かず無駄に辛い時間を過ごしてしまいました😭 皆さんはしないと思いますが、もし「なんだこれ」というエラーが出たら間違ってライブラリを消してないか、見てみると良いかもです！