Node.js(Express)でSequelize cliを用いて MySQLのmigration環境を作成する

Node.jsでアプリケーションを作成しています。
バックエンドからフロントまでを一通り作成を進めていますが、MySQLの環境整備で大きくつまづいたので忘備録のために記載します。

###環境
macOS(big sure 11.2.3)
docker-compose使用
Node.js
フレームワークExpress

package.jsonは下記の通り

```
{
  "name": "forumboard",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "build": "webpack --config webpack.config.js",
    "dev": "nodemon -L ./bin/www",
    "start": "npm run build && nodemon ./bin/www"
  },
  "dependencies": {
    "@fortawesome/fontawesome-free": "^5.15.3",
    "bootstrap": "^4.6.0",
    "cookie-parser": "~1.4.4",
    "crypto-js": "^4.0.0",
    "debug": "~2.6.9",
    "ejs": "~2.6.1",
    "express": "~4.16.1",
    "http-errors": "~1.6.3",
    "jquery": "^3.6.0",
    "jsonwebtoken": "^8.5.1",
    "morgan": "~1.9.1",
    "mysql2": "^2.2.5",
    "popper.js": "^1.16.1",
    "sequelize": "^6.5.1"
  },
  "devDependencies": {
    "autoprefixer": "^10.2.5",
    "css-loader": "^5.1.3",
    "nodemon": "^2.0.7",
    "sequelize-cli": "^6.2.0",
    "style-loader": "^2.0.0",
    "webpack": "^5.26.3",
    "webpack-cli": "^4.5.0"
  }
}
```

###そもそもマイグレーションって...

初心者すぎてマイグレーションの意味がわかりませんでした。
イマイチアプリの作成において必要を見出せませんでした。。。
そして諦めずに調べた結果、自分の中で落とし所として
"開発においてデータベースの状態を管理するファイルを保存しておき、必要に応じて適切なデータベースの状態へ移行できる仕組み"
という感じで認識しました。
（誰か上手な表現がありますと教えていただきたいです。。）

###マイグレーション環境の準備

インストールはnpmパッケージを使用します。


```javascript
npm install --save-dev sequelize-cli
npx sequelize-cli init //create project
```

initを実行することで、下記フォルダが作成されます。
フォルダについて簡単に解説すると。

>seeders

サンプル（テスト）データの保存。まだアプリ環境が構築できていないけど、データのやりとりを確認したい場合にサンプルデータを事前に用意しておくことが可能。
こちらもタイムスタンプが用意されているので、履歴を追えることが可能

>models

アプリケーションで実際にDBとやりとりするファイル。詳細は後ほど記載しますが、classを用いて各テーブルの関数。リレーションなどの設定をおこないます。

>migrations

日時の表示されたjsファイルで、データーベースのテーブル情報が含まれている。この情報を元に初期テーブルを構築する。

>config

使用する環境状況に応じてDB(MySQL)の接続情報を設定が可能。develop,test,productionと設定が可能です。

これらを順番にExpress内で稼働できるように、接続環境を準備していきます。

####configファイルの編集（参考サイトは[こちら](https://ishida-it.com/blog/post/2019-11-23-docker-nodejs-mysql/))
sequelize cliにてinitを実行した際に"config.json"が生成されますが、docker-compose上では環境変数によってログイン情報などを管理するため、jsonファイルをそのまま使用することができません。そのため、jsファイルとして変換し環境変数が使えるようにconfig.jsonを編集していきます。

<<編集項目>>
・インポートファイルの修正
・config.jsonをjsファイルへの置き換え

####config.jsonをjsファイルへの置き換え

``` 
変更前 config.json
{
  "development": {
    "username": "root",
    "password": null,
    "database": "database_development",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": null,
    "database": "database_production",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}
```

```javascript
変更後(config.js)
module.exports = {
  development: {
    username: process.env.MYSQL_ROOT_USER,
    password: process.env.MYSQL_ROOT_PASSWORD,
    database: process.env.MYSQL_DATABASE,
    host: 'mysql',
    dialect: 'mysql',
  },
  test: {
    username: 'root',
    password: null,
    database: 'database_test',
    host: '127.0.0.1',
    dialect: 'mysql'
  },
  production: {
    username: 'root',
    password: null,
    database: 'database_production',
    host: '127.0.0.1',
    dialect: 'mysql'
  }
};
```

変更箇所はmodule.exportsの追加です。
jsファイルに変更することで環境変数を用いることが可能になりました。
そのため、docker側で設定ができれば反映してくれます。

#####インポートファイルの修正
このconfigファイルは、modelsフォルダのindex.jsにて読み込まれます。
ここのjsonをjsに修正します。

```javascript
const config = require(__dirname + '/../config/config.json')[env];
```

以上で、修正が完了です。
余談になりますが、process.envファイルってどう設定されているかわかりますか？
私は、恥ずかしながらわかりませんでした。。。
そこでgoogle先生の活用です。

envファイルの説明については[こちら](https://blog.cloud-acct.com/posts/u-env-docker-compose/)

上記参考サイトを引用すると、
envファイルをコンテナへ展開することにより、process.envファイルに反映されます。
今回のケースであれば、Docker-compose.ymlファイルにて

```
    env_file: 
      - ./app.env
```

上記のように定義することで反映されます。
確認したい場合には、ターミナル上で下記を入力することで確認が可能です。

```
docker-compose exec [サービス名] node
>process.env
```

以上が、config.jsファイルの編集となります。