読者です 読者をやめる 読者になる 読者になる

ここにタイトルが入ります

デザイン&プログラミングのことも書くし、それ以外のことも書く。

PadrinoでBootstrap4(α)を管理するためにnpmを使う→Herokuにデプロイ

Padrino gulp npm

ちょっとしたサイトをPadrinoで作る際、Bootstrap4(公開時はまだα版)を使ってみることにしました。 せっかくなのでnpmを利用してJS及びCSSを管理することに。

理解できてない部分もありますがとりあえずメモ。

Bootstrap4をnpmで管理

Padrinoでプロジェクトを作った後、npm initなんかでpackage.jsonを作っておく。

参考にさせていただきました:
npmでnode.jsのpackageを管理する - Qiita

npmコマンドでインストールします。

$ npm install bootstrap@4.0.0-alpha.2 --save-dev

これで./node_modules/bootstrap/以下に必要な物がダウンロードされます。

gulpでJS/CSSを取り込む

Padrinoは必要なアセットファイルをpublic以下においておく必要があります。
gulpを使って、Bootstrapと自身で用意したJS/CSS(SCSS)をまとめてpublic以下に置くことにしました。

※PadrinoでSCSSのコンパイルは可能ですが、そちらは利用せずgulpでおこないました。

gulpのタスクとして

  1. Bootstrapと自身で用意したSCSSをコンパイルして1ファイルにまとめてpublic/stylesheetsに配置するタスク
  2. SCSSに変更を加えたら1を実行する監視タスク
  3. Bootstrapと自身で用意したJSをコンパイルして1ファイルにまとめてpublic/javascriptsに配置するタスク
  4. JSに変更を加えたら3を実行する監視タスク

の4つを作成。

ソース

gulpタスクはimport_assets.jsにまとめて記載。
詳細は省く。

Gulp task to import assets (bootstrap) at Padrino ...

SCSS

SCSSに関しては、gulp-sassを使ってBootstrapと自前のSCSSをまとめてコンパイルしています。
同時にsourcemapの作成やminifyも行っています。

JS

JSはbrowserifyを使ってbootstrap含め必要なモジュールをまとめています。
こちらもsourcemapの作成とminifyを行っています。

参考にさせていただきました:
browserify-shimを使って、CDN経由で外部JSライブラリをrequireする | mae's blog Gulp + browserify + watchify + gulp-sass で自動高速コンパイル環境 – モンキーレンチ

JSのコンパイル(browserify)で悩んだ部分

やりたいことは自前のmain.jsでbootstrapのJSを読みこむこと。

import 'bootstrap';

そのための設定をpackage.jsonでおこないました。
自分の認識ががあっているのかどうか怪しい。。

抜粋

"browser": {
  "bootstrap": "./node_modules/bootstrap/dist/js/bootstrap.js"
},
"browserify": {
  "transform": [
    "browserify-shim"
  ]
},
"browserify-shim": {
  "bootstrap": {
    "depends": [
      "jquery:jQuery",
      "tether:Tether"
    ]
  }
}
  1. main.jsでimport(require)するために、browserにbootstrapの場所を指定。

  2. bootstrap.jsはCommonJS的に?module.exportされていないので、そういうものをモジュールのように取り込むためにbrowserify-shimを使う。

  3. bootstrapはjQueryやTetherに依存しているので、browserifyで取り込む際にそれらを参照させる必要がある。 それがbrowserify-shimの設定部分に記述してある(depends)。 依存するモジュールとして、npmでインストールしているjqueryを「jQuery」に、tetherを「Tether」として呼び出せるように指定してあげる。

これでguplタスクを動かして、無事bootstrap4のJSを取り込んだCSSを作成することができました。

Herokuで動かす

Herokuでアプリケーションを立ち上げるときに、npmのインストールがどうすれば実行されるのかわからなくて少し悩んだので。

まずnpm installが完了したらアセットファイル作成のgulpタスクを実行するようpackage.jsonに書いておきます。

抜粋

"scripts": {
    "postinstall": "gulp import-assets"
 },

とりあえず作ったPadrinoアプリをHerokuにプッシュしてみたところ、bundle install ~ Webサーバーの立ち上げはやってくれるんだけど, (Gemfileとかconfig.ruを見て実行してくれてる?) npmに関しては何もやってくれない。

調べてみるとbuildをおこなってくれるbuildpackの設定をする必要があるみたい。

参考にさせていただきました:
herokuにデプロイするときでもgruntしたい!(+rubyサーバー) - Kesin's diary

公式のドキュメントにちょうどやりたいことが載っていた。
Using Multiple Buildpacks for an App | Heroku Dev Center

まずrubyアプリケーションのビルドを行ってくださいという設定

$ heroku buildpacks:set heroku/ruby

次にnode.jsのビルドもお願いする設定。indexは順番の指定っぽい

$ heroku buildpacks:add --index 1 heroku/nodejs

これでHerokuにプッシュするとpakage.jsonを見てnpm installをおこなってくれる。

もう一つ困ったこと

npmのライブラリはあくまでPadrinoで読み込むJSやCSSを管理するものなので、 インストールするときに--save-devを付けてインストールしていました。

しかしHerokuへのデプロイ時にはdevDependenciesのライブラリはインストールされません(本番環境だから?) なのでdevDependenciesもインストールするよう環境変数を設定する必要がありました。

$ heroku config:set NPM_CONFIG_PRODUCTION=false

参考にさせていただきました:
sprocketsではなくnodejsを使うRailsアプリをHerokuにデプロイする方法 - Qiita


これでHerokuにプッシュしたところ、npmのインストール&gulpタスク、gemのインストールが走り、 bootstrap4を読み込んだ状態でPadrinoアプリが立ち上がりました!

JS初心者がつまずくのはJSの書き方よりもこういったモジュール管理とかそういったところなのではと。