webpackでbuildした際、そのbuild versionをブラウザから簡単に確認できるようにする

## はじめに
検証・本番環境で今見ているものが一体どのバージョンのものなのか？が分からなくなる事があると思う。そんな時、手軽にバージョン確認できればいいなという事で、[webpack-version-file](https://github.com/fed/webpack-version-file)を利用して静的ファイルの配信を行うフォルダに`version.json`を生成する方法を試してみたのでそれについて備忘録を残す。

[^1]: アイディアの1つとしては、APIで`/healthcheck`のようなエンドポイントを設け、APIサーバーが動くために必要になる他のMySQLやRedis等が生きている事を確認しつつ、そこでbuildバージョンをJSONで返す、というのがあるだろう（ただし、こういうhealthcheckのエンドポイントはセキュリティのためにALBなどでのIP制限は必須になると思われる。

※フロントエンドとバックエンドのプロジェクトが分かれている場合、今回見ていく方法では、フロントエンドのプロジェクトのbuildバージョンの確認はできるようにはなるが、バックエンドの方は別の方法でbuildバージョンを確認できるようにする必要があると思われる[^1]。理由は今回見ていく方法は、

- distディレクトリ以下にversion確認できるファイルを生成  
→ブラウザ上からフロントエンドのbuildバージョンが確認できるようになる

という方法なため（distはWebサーバーで配信するstaticな資材の置き場をイメージしており、Expressで言えば[Serving static files in Express](https://expressjs.com/en/starter/static-files.html)の事）。ただし、モノレポの構成で、dockerイメージをbuildするようなプロジェクト構成であれば、フロントエンド・バックエンドが一緒になるのでこの方法で両方のバージョン（いつ時点でのbuild成果物か？）の確認できるかもしれない。

※以下では、既にwebpackの設定は済んでいる事を前提にしている。

## 結論　どうやるのか？
[webpack-version-file](https://github.com/fed/webpack-version-file)を利用する。

```console
[study@localhost travel-app]$ npm install --save-dev webpack-version-file
```
```js
...
const VersionFile = require('webpack-version-file');

module.exports = {
	...
	plugins: [
		...
		new VersionFile({
			output: './dist/version.txt'
		})
	]
};
```

上記のようにする事で、以下のようにブラウザから簡単にbuildバージョンを確認できるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/0b58c15a-9f92-d2ba-3148-ca0aa8d0ef6c.png)

### Vue.js（2.x）だとどうなるか？
Vue-CLIであればvue.config.jsを以下のように設定する事で同じように、同様の事が実現できる。

```js
...
const VersionFile = require('webpack-version-file');
const { DateTime } = require('luxon');

const dt = DateTime.now();

module.exports = {
	configureWebpack: {
		plugins: [
			...
			new VersionFile({
				output: './dist/version.txt'
			})
		]
	}
};
```

ソースコード全体は以下。

https://github.com/yuta-katayama-23/intro-vuecli/commit/a0147563c9ec8df6a872ed7a04446cf259786c7b

## カスタマイズする
上記のままでもいいが、少し他の情報を加えたりデフォルトだとtxtでファイルが作成されてしまうので、json形式で作成されるようにしてみたいと思う。設定としては以下のようにしてみた。

```js
...
const { DateTime } = require('luxon');
const dt = DateTime.now();

module.exports = {
	...
	plugins: [
		...
		new VersionFile({
			output: './dist/version.json',
			templateString: `{${['version', 'buildDate', 'timestamp', 'environment']
				.map((key) => `"${key}": "<%= ${key} %>"`)
				.join(',')}}`,
			data: {
				buildDate: dt.toISO(),
				timestamp: dt.toSeconds(),
				environment: process.env.NODE_ENV || 'development'
			}
		})
	]
};
```

上記のように設定すると、以下のようにブラウザからそのバージョンを確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/57073009-de7a-5f74-1ffa-76083d9cde2b.png)

※JSONにした理由としてはChromeの拡張機能に[JSON Viewer](https://chrome.google.com/webstore/detail/json-viewer/gbmdgpbipfallnflgajpaliibnhdgobh?hl=ja)などブラウザ上でJSONを見やすくする拡張機能があるため。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/c7be3c88-da72-4992-0e69-e78289ff00b0.png)

ソースコード全体は以下。

https://github.com/yuta-katayama-23/travel-app/commit/d66f30c1d4e222521e6961b556c4063dbc2d9d16

## まとめとして
今回はwebpackのプラグインを使って簡単にbuildバージョンを確認できるようにする方法についてみてきた。フロントエンドについてはこれで最低限の確認はできるだろう。

※ちなみに、モノレポ構成を取る方法としては[【フロントエンド、バックエンドを一つのリポジトリで管理】monorepoを実現できるNxをさわってみた](https://dev.classmethod.jp/articles/monorepo-nx/)にあるような方法があるし、[vue-cli](https://github.com/vuejs/vue-cli/tree/v2)時代には[vue-cli-plugin-express](https://github.com/mathieutu/vue-cli-plugin-express)というプラグインで簡単にVue × Expressのモノレポ構成を作れたりした。