[解決]Dockerで構築した@vue3でHMR(Hot Module Replacement)効かない問題とwebpackの高速化[Docker]

以下の記事を参考にVueCLIを使いプロジェクトを作成したが、ホットリロードが効かなかったので解決した。
[Vue.js + Express + Sequelize + DockerでCRUD搭載のTodoリストを作ってみる](https://qiita.com/yoshiplum/items/129e7ad1ffc3a02b9eb2)


<a data-ofuse-widget-button href="https://ofuse.me/o?uid=29455" data-ofuse-id="29455" data-ofuse-text="OFUSEする" data-ofuse-style="rectangle">OFUSEする</a>（なげ銭）

### 環境
```
$ vue --version
@vue/cli 4.5.4
```

```package.json
  "dependencies": {
    "core-js": "^3.6.5",
    "vue": "^3.0.0",
```


## 結論
結論だけ書くと、プロジェクトのルートに以下を追加(srcとかと同じ階層)

```vue.config.js
module.exports = {
  configureWebpack: {
    devServer: {
      watchOptions: {
        poll: true
      }
    }
  }
}
```
## pollってなんぞ？

Webpackのpollという設定をいじっているけどpollってなんぞやと思ったので調べた。

>これによると、 Webpack の watch は inotify というLinux 2.6 から追加されたファイルシステムのイベントを監視する仕組みを使っているらしい。しかし、ホスト上のファイルをVirualBoxに同期するのにNFSを使っていて inotify は NFS に対応していない、とかそんな感じのようですよ。
[Docker内で Webpack の watch でファイルの変更を検知する](http://hironemu.hatenablog.com/entry/20170909/1504966556)


> ポーリング（polling）とは、通信やソフトウェアにおいて、競合を回避したり、送受信の準備状況を判断したり、処理を同期したりするために、複数の機器やプログラムに対して順番に定期的に問い合わせを行い、一定の条件を満たした場合に送受信や処理を行う通信及び処理方式のことである。
Wikipedia: [ポーリング (情報)](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0_(%E6%83%85%E5%A0%B1)#:~:text=%E3%83%9D%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0%EF%BC%88polling%EF%BC%89%E3%81%A8%E3%81%AF%E3%80%81,%E6%96%B9%E5%BC%8F%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82)

なるほどねん。

## ビルド遅いねん
HMRできたのはいいけどビルド時間が遅い...

```
DONE Compiled successfully in 25403ms9:05:21 AM
```
25秒は流石にかかりすぎでしょう...

### vueのビルドについておさらい
vue-cliでプロジェクトを生成するとモジュールバンドラは自動的にwebpackになると思います。
モジュールバンドラとは複数のファイルを１つにまとめて出力してくれるツールです。
主にJavaScriptをまとめる役割が多いですが、cssや画像もまとめてくれる場合もあります。

パンドラを使う利点としてはいくつかありますが、代表的なものは自動的に依存関係を解決することが挙げられます。
>JSファイル間の依存関係を自動で解析し、一つのファイルとしてまとめてくれます！[最近のフロントエンドでのwebpackの重要性について考えてみる](https://qiita.com/kazukiii/items/4a8fece8881bc79b18e2)

他参考
- [Webpackってどんなもの？
](https://qiita.com/kamykn/items/45fb4690ace32216ca25)

vueではさまざまなビルドがあり、特性が違います。
- [さまざまなビルドについて](https://jp.vuejs.org/v2/guide/installation.html#%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%93%E3%83%AB%E3%83%89%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
- [Vue.jsの完全ビルドとランタイムビルドの違い
](https://qiita.com/sansaisoba/items/58f8176f6e462fe4d591)


### vue-cliにおけるwebpack
vue-cliを使うとwebpackを使う際の設定なども出力してくれるので、我々がモジュールバンドラをあまり理解していなくてもその恩恵に預かることができます。

- [webpack(vue-cli)は何をしてくれるものなのか](https://scrapbox.io/vue-yawaraka/webpack(vue-cli)%E3%81%AF%E4%BD%95%E3%82%92%E3%81%97%E3%81%A6%E3%81%8F%E3%82%8C%E3%82%8B%E3%82%82%E3%81%AE%E3%81%AA%E3%81%AE%E3%81%8B)


## それにしてもwebpack遅い！
ということで、webpackの高速化に取り組みたいと思います。
`cache-loader`という物を導入していきます。

```
DONE Compiled successfully in 25403ms9:05:21 AM
```
現状は25秒かかってしまう。

Dockerから開いたcliから入力しましょう！
`npm install --save-dev cache-loader`

```vue.config.js
module.exports = {
  //以下を追加
  configureWebpack: {
    module: {
        rules: [
          {
            test: /\.js$/,
            use: ['cache-loader', 'vue-loader'],
            include: path.resolve('src'),
          },
        ],
      },
  },
  devServer: {
    watchOptions: {
      poll: true,
    },

    port: 8080,
    host: "0.0.0.0",
    useLocalIp: true,
  },
};
```

参考
- [webpack/cache-loader](https://webpack.js.org/loaders/cache-loader/)
- [Vue Vli/Working with Webpack](https://cli.vuejs.org/guide/webpack.html#simple-configuration)
- [vue.config.js で webpackの設定を使えるようにする方法](https://qiita.com/uturned0/items/5fdf2d92548274fe56e3)
- [thread-loaderとcache-loaderでwebpackのビルドを高速化する](https://dackdive.hateblo.jp/entry/2017/10/10/100000)

と思ったけどエラー出た

```
ERROR Error loading /vue/frontapp/vue.config.js:

ERROR ReferenceError: path is not defined

ReferenceError: path is not defined

at Object.<anonymous> (/vue/frontapp/vue.config.js:8:22)

at Module._compile (internal/modules/cjs/loader.js:959:30)

at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)

at Module.load (internal/modules/cjs/loader.js:815:32)

at Function.Module._load (internal/modules/cjs/loader.js:727:14)

at Module.require (internal/modules/cjs/loader.js:852:19)

at require (internal/modules/cjs/helpers.js:74:18)

at exports.loadModule (/vue/frontapp/node_modules/@vue/cli-shared-utils/lib/module.js:79:14)

at Service.loadUserOptions (/vue/frontapp/node_modules/@vue/cli-service/lib/Service.js:330:22)

at Service.init (/vue/frontapp/node_modules/@vue/cli-service/lib/Service.js:70:30)

npm ERR! code ELIFECYCLE

npm ERR! errno 1

npm ERR! frontapp@0.1.0 serve: `vue-cli-service serve`

npm ERR! Exit status 1



npm ERR!

npm ERR! Failed at the frontapp@0.1.0 serve script.

npm ERR! This is probably not a problem with npm. There is likely additional logging output above.


npm ERR! A complete log of this run can be found in:

npm ERR! /root/.npm/_logs/2020-11-01T12_06_41_379Z-debug.log
```

頭に `const path = require('path');`を追加

```
const path = require('path');
module.exports = {
  configureWebpack: {
    module: {
        rules: [
          {
            test: /\.js$/,
            use: ['cache-loader'],
            include: path.resolve('src'),
          },
        ],
      },
  },
  devServer: {
    watchOptions: {
      poll: true,
    },

    port: 8080,
    host: "0.0.0.0",
    useLocalIp: true,
  },
};
```

```
DONE Compiled successfully in 5655ms6:57:29 AM
```
25.4秒から5.6秒まで短縮:tada::tada::tada:

### ついでになんかエラー出てたから解決
```
(node:20) [SEQUELIZE0004] DeprecationWarning: A boolean value was passed to options.operatorsAliases. This is a no-op with v5 and should be removed.
```

[DeprecationWarning：ブール値がoptions.operatorsAliasesに渡されました。これはv5では何もしないので、削除する必要があります](https://qastack.jp/programming/58593200/deprecationwarning-a-boolean-value-was-passed-to-options-operatorsaliases-this)
を参考に
config/config.jsonの`"operatorsAliases": false` を `"operatorsAliases": 0`に変更したら解決。

行き詰まったら飯食って風呂入って原神して寝る
[話題作『Helltaker』の魅力に迫る！陽炎01型氏インタビュー「困ったら風呂入って飯食って寝ましょう」【有志日本語化の現場から】](https://www.gamespark.jp/article/2020/05/24/99296.html)
え？ハクスラ苦手？そんな君にはタワーディフェンスのアークナイツ
え？タワーディフェンス好きじゃない？そんな君にはタワーオフェンスの少女前線がおすすめだ！

<a data-ofuse-widget-button href="https://ofuse.me/o?uid=29455" data-ofuse-id="29455" data-ofuse-text="OFUSEする" data-ofuse-style="rectangle">OFUSEする</a>（なげ銭）