Ruby on Rails + webpack-dev-server で Development.
Rails で JavaScript が必要なプライベートプロジェクトでは、ながらく Npm + Watchify + Gulp + Rails を手動起動などしながらすすめていましたが、最近、意を決して Yarn + Webpack + Rails に変更しました。そこで、Rails と JavaScript の接合点も Railsway にのった設定に変えようと思いました。(今までは public/css を直接参照していた)
ざっと検索したところ、webpack-dev-server 経由で JavaScript を参照する場合、あらたな helper を用意する方式しか見つけられなかったので、assets の path を変更する方式をメモります。
概要
webpack-dev-server を port 5001 で起動し、Rails の assets 用のタグがそれを参照するようにします。
Rails configuration
#config/environments/development.rb Rails.application.configure do # snip config.action_controller.asset_host = 'http://localhost:5001' end
Webpack configuration
Files place
JavaScript ファイルとして app1.js, app2.js, app3.js が書きだされる想定です。
- app # 他 Rails のディレクトリ - public - lib - sass - common.sass - src - app1 - index.js - app2 - index.js - app3 - index.js - package.json
package.json
style-loader を噛ませるととても遅いので、sass は node-sass ダイレクトで書きだします。書きだし先のディレクトリを参照できるように、webpack-dev-server を --content-base でルートを public に合わせておきます。
"scripts": { "watch": "webpack-dev-server --progress --colors --config ./webpack/dev.config.js --port 5001 --content-base ../public", "watch-sass": "node-sass --watch ./sass/common.sass ../public/stylesheets/common.css" },
webpack.config.js
publicPath を javascripts という、Rails ネーミングに合わせておきます。
sass も webpack-dev-server を通す場合、こちらにも publicPath が必要ですが、こちらは ExtractTextPlugin 側に設定しなければならない点に注意します。
const entryPoints = require('glob').sync('./src/*/index.js').reduce((a, v)=> { a[v.split('/')[2]] = v return a }, {}) const jsConfiguration = { entry: entryPoints, output: { publicPath: 'javascripts', filename: "[name].js" }, module: { loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' } ] } } const ExtractTextPlugin = require('extract-text-webpack-plugin') const cssConfiguration = { entry: './sass/common.sass', output: { publicPath: 'stylesheets', filename: "common.css" }, module: { loaders: [ { test: /\.sass|\.scss/, loader: ExtractTextPlugin.extract({ fallbackLoader: "style-loader", loader: "css-loader?minimize!sass-loader", publicPath: 'stylesheets', }) } ] }, plugins: [ new ExtractTextPlugin("common.css") ] } module.exports = [ jsConfiguration, // cssConfiguration ]
できあがり
これで以下のようにコンパイルされ、webpack-dev-server は狙ったファイルを返すようになりました。
= javascript_include_tag('app1.js')
<script src="http://localhost:5001/javascripts/app1.js"></script>
なお Rails 起動時には webpack-dev-server も同時に起動することになりますが、Procfile.dev を用意して foreman で起動すると手間がかからなくて良いようです。
web: bundle exec rails server -p 5000 compile: cd lib/es && yarn run watch compile: cd lib/es && yarn run watch-sass
foreman start -f Procfile.dev