anekawaです。
ちょっと前に個人で開発したrailsアプリをHerokuにデプロイしようとしたときにハマったことを書いておこうと思います。
前提
- babelやautoprefixerを使いたかったのでフロント周りはwebpackを使う
- Herokuへデプロイした際に
webpack
によるビルドを走らせたかった - 開発環境ではrootディレクトリ直下に
frontend/
というディレクトリを作り、その中にフロントエンド関係のソースを詰めていた(package.json
や/node_modules
を含む) frontend/
ディレクトリ内でwebpack
によるビルドをしていた- turbolinksやsprocketsは使っておらず、webpackerも使っていない
- パッケージマネージャはyarnを使用
- 開発時のディレクトリ構成は以下
rails_root
├── appなどrailsディレクトリ達
└── frontend
├── package.json
├── scripts
│ └── index.js // エントリーポイント
├── webpack.config.js
└── yarn.lock
ハマったこと
前提3で書いてあるようにして開発を進めていたため、開発環境では
cd frontend
yarn run webpack --config ./webpack.config.js --mode development
という感じでwebpackのビルドを行っていました(厳密にはwebpack-dev-server
を使用)。
公式によれば、yarn
の導入にはpackage.json
の中に
"engines": {
"yarn": "1.x"
}
を記述しないといけないみたいなので、これとビルド用npm scripts
である
"scripts": {
"postinstall": "cd ./frontend && yarn && yarn run webpack --config ./webpack.config.js --mode production"
},
を、frontend/
直下のpackage.json
に書いていざデプロイすると、
$ git push heroku master
Enumerating objects: 6484, done.
Counting objects: 100% (6484/6484), done.
Delta compression using up to 2 threads.
Compressing objects: 100% (5289/5289), done.
Writing objects: 100% (6484/6484), 31.05 MiB | 1.55 MiB/s, done.
Total 6484 (delta 840), reused 6454 (delta 818)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Node.js app detected
remote:
remote: -----> Creating runtime environment
remote:
remote: NPM_CONFIG_LOGLEVEL=error
remote: NODE_ENV=production
remote: NODE_MODULES_CACHE=true
remote: NODE_VERBOSE=false
remote:
remote: -----> Installing binaries
remote: engines.node (package.json): 8.11.3
remote: engines.npm (package.json): unspecified (use default)
remote:
remote: Resolving node version 8.11.3...
remote: Downloading and installing node 8.11.3...
remote: Using default npm version: 5.6.0
remote: Resolving yarn version 1.x...
remote: Downloading and installing yarn (1.13.0)...
remote: Installed yarn 1.13.0
remote:
remote: -----> Building dependencies
remote: Installing node modules (package.json)
remote: up to date in 0.075s
remote:
remote: -----> Caching build
remote: - node_modules (nothing to cache)
remote:
remote: -----> Pruning devDependencies
remote: Skipping because npm 5.6.0 sometimes fails when running 'npm prune' due to a known issue
remote: https://github.com/npm/npm/issues/19356
remote:
remote: You can silence this warning by updating to at least npm 5.7.1 in your package.json
remote: https://devcenter.heroku.com/articles/nodejs-support#specifying-an-npm-version
remote:
remote: -----> Build succeeded!
remote: ! This app may not specify any way to start a node process
remote: https://devcenter.heroku.com/articles/nodejs-support#default-web-process-type
remote:
remote: -----> Ruby app detected
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.5.1
remote: -----> Installing dependencies using bundler 1.15.2
remote: Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment
# (gemのインストール等なので割愛)
remote: Warning: the running version of Bundler (1.15.2) is older than the version that created the lockfile (1.16.3). We suggest you upgrade to the latest version of Bundle
r by running `gem install bundler`.
remote: -----> Compressing...
remote: Done: 51.3M
remote: -----> Launching...
remote: Released v6
remote: https://XXXXXX.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/XXXXXX.git
* [new branch] master -> master
というログが出ました(開発環境をこの記事を書くために再現した環境でやっているので実際のログとはちょっと違うかも)。
一見成功しているかと思ったのですが、よく読むとnpm scripts
に指定したデプロイ時のビルドコマンドが一ミリも動いてないです。
もっと言うと、そもそもyarnのパッケージインストールも動いていません。
原因
色々触ってるうちに気づいたのですが、package.json
の場所がルート直下でなかったのが原因だったようです。
フロントエンド周りで使うものをfrontend/
ディレクトリに詰め込んだのが原因だったっぽいですね。
はじめはかなりググったりしたんですが、気づいてしまったらかなり単純なことでした…
対策
はじめはfrontend/
内のpackage.json
を適宜書き換えてルート直下に移してしまおうかと思ったのですが、それだと/node_modules
がルート直下に作られてしまいます。
rails
関係のファイルとフロント周りのファイル分けたかったので以下のようにしました。
- ルートディレクトリ直下には
yarn
のインストールとデプロイ時のビルドを実行するためのスクリプトを書いただけのpackage.json
を配置 frontend/
には、具体的に使用するパッケージを載せたpackage.json
を配置
1. ルートディレクトリ直下にはyarn
のインストールとデプロイ時のビルドを実行するためのスクリプトを書いただけのpackage.json
を配置
Herokuがデフォルトで認識するpackage.json
はルートディレクトリ直下のもののようで、ここに先述した
"engines": {
"yarn": "1.x"
}
を書いておきます。
また、具体的なwebpack
によるビルドコマンドは先述したものを少し変えて、
"scripts": {
"postinstall": "cd ./frontend && yarn && yarn run webpack --config ./webpack.config.js --mode production"
},
としています。
こうすれば、frontend/
内でyarn install
が走るため、/node_modules
がルートディレクトリ直下に作成されることを避けられます。
2. frontend/
には、具体的に使用するパッケージを載せたpackage.json
を配置
フロント周りのソースを詰めたfrontend/
ディレクトリ内に配置するpackage.json
には、ビルドのために使う諸々のパッケージを書きます(yarn add hoge
で書き込まれるあれ)。
以上のことをすれば大丈夫でした。
あとはgit push heroku master
でいけるはずです。
おわりに
Herokuを使ったのは久々でしたが、ちょこっと作ったものをさっとデプロイするのにはやはり便利でした。
今回の開発でどうせならと思ってホビープランにも入ったので、来年はもっと個人開発をしていこうかなと思います。