Herokuでsequlizeコマンドを使ってmigrationしようとしたらハマった話

# 要点
- sequelize-cliはdevDependenciesではなくdependenciesに書く
- migrationsフォルダにmigration用のjsファイルを入れる

# いきさつ
https://www.slideshare.net/DeveloperForceJapan/nodejsheroku
このスライドの25枚目を見て
`$ heroku run sequelize db:migrate`
としても動かなかった。

# 原因調査
実行結果を見てみる

```
sh-obata@ELLEN MINGW64 /e/Work/StaminaGroove (develop)
$ heroku run sequelize db:migrate -a stamina-groove
Running sequelize db:migrate on stamina-groove... starting, run.1241 (Free)
Running sequelize db:migrate on stamina-groove... connecting, run.1241 (Free)
Running sequelize db:migrate on stamina-groove... up, run.1241 (Free)
bash: sequelize: command not found
```
sequelizeコマンドがないと怒られた。
node_modules/.bin の中にいるバイナリを直接叩かないとダメか？

```
sh-obata@ELLEN MINGW64 /e/Work/StaminaGroove (develop)
$ heroku run ./node_modules/.bin/sequelize db:migrate -a stamina-groove
Running ./node_modules/.bin/sequelize db:migrate on stamina-groove... starting, run.1844 (Free)
Running ./node_modules/.bin/sequelize db:migrate on stamina-groove... connecting, run.1844 (Free)
Running ./node_modules/.bin/sequelize db:migrate on stamina-groove... up, run.1844 (Free)
bash: ./node_modules/.bin/sequelize: No such file or directory
```
あれ？sequelizeのバイナリがない…？

sequelize-cliがインストールされてるのか見てみる。

```
sh-obata@ELLEN MINGW64 /e/Work/StaminaGroove (develop)
$ heroku run bash
Running bash on shielded-plains-33969... starting, run.2181 (Free)
Running bash on shielded-plains-33969... connecting, run.2181 (Free)
Running bash on shielded-plains-33969... up, run.2181 (Free)

~ $ cd node_modules
cd node_modules

~/node_modules $ ls
ls
@types               fresh                 postgres-bytea
accepts              graceful-readlink     postgres-date
acorn                http-errors           postgres-interval
acorn-globals        iconv-lite            promise
align-text           inflection            proxy-addr
amdefine             inherits              qs
any-promise          ipaddr.js             range-parser
array-flatten        is-bluebird           raw-body
asap                 is-buffer             repeat-string
basic-auth           is-promise            retry-as-promised
bluebird             jade                  right-align
body-parser          jstransformer         safe-buffer
buffer-writer        kind-of               safer-buffer
bytes                lazy-cache            semver
camelcase            lodash                send
center-align         longest               sequelize
character-parser     media-typer           sequelize-pool
clean-css            merge-descriptors     serve-static
cliui                methods               setprototypeof
cls-bluebird         mime                  shimmer
commander            mime-db               source-map
constantinople       mime-types            split
content-disposition  minimist              statuses
content-type         mkdirp                through
cookie               moment                toposort-class
cookie-parser        moment-timezone       transformers
cookie-signature     morgan                type-is
css                  ms                    uglify-js
css-parse            negotiator            uglify-to-browserify
css-stringify        on-finished           unpipe
debug                on-headers            utils-merge
decamelize           optimist              uuid
depd                 packet-reader         validator
destroy              parseurl              vary
dottie               path-to-regexp        void-elements
ee-first             pg                    window-size
encodeurl            pg-connection-string  with
escape-html          pg-int8               wkx
etag                 pg-pool               wordwrap
express              pg-types              xtend
finalhandler         pgpass                yargs
forwarded            postgres-array
```
sequelize-cliがいない。

sequelizeコマンドのいる /node_modules/.bin の中も見てみる。

```
~/node_modules $ cd .bin
cd .bin

~/node_modules/.bin $ ls
ls
acorn  cleancss  jade  mime  mkdirp  semver  uglifyjs  uuid
```
sequlizeいない。

# 原因
sequelize-cliをdevDependenciesに書いていたのがまずかったっぽい。
devDependenciesに書かれてたものはインストールされてなかった。

```(変更前)package.json
{
  (中略)
  "scripts": {
    "start": "node ./bin/www",
    (中略)
    "sequelize": "sequelize"
  },
  "dependencies": {
    (中略)
    "sequelize": "^5.5.0"
  },
  "devDependencies": {
    (中略)
    "sequelize-cli": "^5.4.0"
  }
}
```
こうすると使えるようになった。

```(変更後)package.json
{
  (中略)
  "scripts": {
    "start": "node ./bin/www",
    (中略)
    "sequelize": "sequelize"
  },
  "dependencies": {
    (中略)
    "sequelize": "^5.5.0",
    "sequelize-cli": "^5.4.0"
  },
  "devDependencies": {
    (中略)
  }
}
```

# migrationが失敗する

```
~ $ sequelize db:migrate
sequelize db:migrate

Sequelize CLI [Node: 10.15.3, CLI: 5.4.0, ORM: 5.8.4]

Loaded configuration file "config/config.json".
Using environment "production".

ERROR: ENOENT: no such file or directory, scandir '/app/migrations'
```

migrationsフォルダがないと怒られた。しくしく。
リポジトリ直下にmigrationsフォルダとmigration用のjsファイルを追加して再度実行。

```
sh-obata@ELLEN MINGW64 /e/Work/StaminaGroove (develop)
$ heroku run bash
Running bash on shielded-plains-33969... starting, run.3264 (Free)
Running bash on shielded-plains-33969... connecting, run.3264 (Free)
Running bash on shielded-plains-33969... up, run.3264 (Free)

~ $ ls
ls
README.md  bin     migrations  node_modules       package.json  routes
app.js     config  models      package-lock.json  public        views

~ $ sequelize db:migrate
sequelize db:migrate

Sequelize CLI [Node: 10.15.3, CLI: 5.4.0, ORM: 5.8.4]

Loaded configuration file "config/config.json".
Using environment "production".
== 20190502114420-create-songs: migrating =======
== 20190502114420-create-songs: migrated (1.355s)

== 20190502115801-create-charts: migrating =======
== 20190502115801-create-charts: migrated (0.080s)

== 20190502120445-create-packages: migrating =======
== 20190502120445-create-packages: migrated (0.056s)

```
できた。

# 余談

使用するgitリポジトリはHeroku GitでもGitHubでもどちらでも動いた。

# 余談その2

なんでsequelize-cliをdevDependenciesにしていたかというと、sequelize-cliは開発中に使用するツールであり、このアプリを使う上では必要ないものだと判断したため、devDependenciesにしていた。
Herokuはdependenciesのみインストールしてるっぽいね。