LoginSignup
7
5

More than 5 years have passed since last update.

Rails-Webpacker-riotを使う前提の環境構築メモ

Last updated at Posted at 2017-02-13

Rails5.1で導入が予定されているWebpackerを使ってみたくて、いろいろ調べたことをまとめます。
以下9つの手順を行った環境をgithubで公開しました。お役に立てるかわかりませんが、ご参考まで。

環境

Rails 5.0.1
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-linux]

Step.1 rails newする

rails new rails-webpacker-riot
cd rails-webpacker-riot

Step.2 gemファイルにwebpackerと書いてbundle install

rails serverとwebpackのバンドル開始を1つのコマンドでできるようになるforemanも入れてみる

Gemfile

gem 'webpacker'
gem 'foreman'

bundle install

Step.3 rails webpacker:installでwebpacker関連のフォルダやファイルが作成される


rails webpacker:install

Step.4 必要なJSパッケージをbin/yarnで追加する

パッケージはyarnで管理される。step.3 でbin/yarnが実行され、次のパッケージがインストールされる

vendor/package.json
{
  "devDependencies": {
    "babel-core": "^6.22.1",
    "babel-loader": "^6.2.10",
    "babel-preset-latest": "^6.22.0",
    "coffee-loader": "^0.7.2",
    "coffee-script": "^1.12.3",
    "path-complete-extname": "^0.1.0",
    "rails-erb-loader": "^3.2.0",
    "webpack": "beta",
    "webpack-dev-server": "beta",
    "webpack-merge": "^2.6.1"
  }
}

自分で追加したいパッケージがあれば、bin/yarn add -Dで追加していく。

bin/yarn add font-awesome font-awesome-webpack2 riot riotjs-loader node-sass sass-loader file-loader url-loader promise-polyfill less babel-preset-es2015-riot bootstrap-sass -D

vendor/package.json
{
  "devDependencies": {
    "babel-core": "^6.22.1",
    "babel-loader": "^6.2.10",
    "babel-preset-es2015-riot": "^1.1.0",
    "babel-preset-latest": "^6.22.0",
    "bootstrap-sass": "^3.3.7",
    "coffee-loader": "^0.7.2",
    "coffee-script": "^1.12.3",
    "file-loader": "^0.10.0",
    "font-awesome": "^4.7.0",
    "font-awesome-webpack2": "^0.0.6",
    "less": "^2.7.2",
    "node-sass": "^4.5.0",
    "path-complete-extname": "^0.1.0",
    "promise-polyfill": "^6.0.2",
    "rails-erb-loader": "^3.2.0",
    "riot": "^3.2.1",
    "riotjs-loader": "^4.0.0",
    "sass-loader": "^5.0.1",
    "url-loader": "^0.5.7",
    "webpack": "beta",
    "webpack-dev-server": "beta",
    "webpack-merge": "^2.6.1"
  }
}

なお、globalにyarnを入れておく必要があるのか、Step.3で合わせてインストールされるのか、よくわからなかった。

Step.5 foremanのProcfileをroot配下に作る

foreman startでProcfileにある2つのコマンドを実行してくれる。

Procfile
webpack: bin/webpack-dev-server
rails: rails s

Step.6 webpack.config関連の設定

webpack.config.js 相当の設定は、config/webpackに格納される。shared, production, developmentとあるので、それぞれ以下の通り設定した。

  • shared.jsのruleに、各パッケージのloaderを設定
  • production.js, development.jsに、webpack.ProvidePluginを設定
config/webpack/shared.js
// Note: You must restart bin/webpack-watcher for changes to take effect

var path = require('path')
var glob = require('glob')
var extname = require('path-complete-extname')

module.exports = {
  entry: glob.sync(path.join('..', 'app', 'javascript', 'packs', '*.js*')).reduce(
    function(map, entry) {
      var basename = path.basename(entry, extname(entry))
      map[basename] = entry
      return map
    }, {}
  ),

  output: { filename: '[name].js', path: path.resolve('..', 'public', 'packs') },

  module: {
    rules: [
      { test: /\.coffee(.erb)?$/, loader: "coffee-loader" },
      {
        test: /\.js(.erb)?$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          presets: [
            [ 'latest', { 'es2015-riot': { 'modules': false } } ]
          ]
        }
      },
      {
        test: /\.erb$/,
        enforce: 'pre',
        loader: 'rails-erb-loader',
        options: {
          runner: '../bin/rails runner'
        }
      },

      // config for riot
      {
        test: /\.tag$/,
        loader: "riotjs-loader"
      },

      // config for font-awesome-webpack2
      {
        test: /\.woff(2)?(\?v=[a-z0-9]\.[a-z0-9]\.[a-z0-9])?$/,
        loader: 'url-loader?limit=100000'
      },
      {
        test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: "file-loader"
      },

      // config for using SCSS.
      {
        test: /\.scss$/,
        enforce: 'pre',
        loader: ['style-loader', 'css-loader', 'sass-loader']
      }
    ]
  },

  plugins: [ ],

  resolve: {
    extensions: [ '.js', '.coffee' ],
    modules: [
      path.resolve('../app/javascript'),
      path.resolve('../vendor/node_modules')
    ]
  },

  resolveLoader: {
    modules: [ path.resolve('../vendor/node_modules') ]
  }
}

config/webpack/development.js
// Note: You must restart bin/webpack-watcher for changes to take effect

var path    = require('path')
var webpack = require('webpack')
var merge   = require('webpack-merge')

var config = require('./shared.js')

module.exports = merge(config, {
  devtool: 'sourcemap',

  stats: {
    errorDetails: true
  },

  output: {
    pathinfo: true
  },

  plugins: [
    new webpack.LoaderOptionsPlugin({
      debug: true
    }),
    // config for riot.
    new webpack.ProvidePlugin({ riot: 'riot' }),
  ]
})
config/webpack/production.js
// Note: You must restart bin/webpack-watcher for changes to take effect

var path    = require('path')
var webpack = require('webpack')
var merge   = require('webpack-merge')

var config = require('./shared.js')

module.exports = merge(config, {
  output: { filename: "[name]-[hash].js" },

  plugins: [
    new webpack.LoaderOptionsPlugin({
      minimize: true
    }),
    new webpack.ProvidePlugin({ riot: 'riot' })
  ]
})

Step.7 app/javascript配下のこと

tagファイルの置き場所

app/javascript配下にフォルダを作り、index.jsを作る。また、このフォルダの中にtagファイルを格納する。今回はmainというフォルダ名にした。

app/javascript/main/index.js
require('./style.scss')
app/javascript/main/style.scss
// for use bootstrap-fonts
$icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/";
@import "~bootstrap-sass/assets/stylesheets/_bootstrap.scss";

packs配下のこと

application.jsで使うパッケージをrequireする。
また、上記で作ったmainフォルダもrequireする。requireされるフォルダにindex.jsがないとうまくコンパイルされない。

app/javascript/packs/application.js
require('font-awesome-webpack2')
require('bootstrap-sass')
require('main')

Step.8 config/environment/development.rb

rails webpack:installのときに一番上に書き込まれているこれをコメントアウトする

config/environment/development.rb
Rails.application.configure do
  # Make javascript_pack_tag load assets from webpack-dev-server.
  config.x.webpacker[:dev_server_host] = "http://localhost:8080"
...

Step.9 herokuへのpushに失敗する問題への対応

対応せずにherokuへpushすると、bin/yarnが実行されずにwebpacker:compileが実行されてしまい、webpackがないため、エラーとなってしまう。

ここで議論されていて、多分rails5.1では問題なくなっているのだろうけど、忘れずに書いておく。

対応1:buildpacksでnodejsを最初に行うよう設定

$ heroku buildpacks:set heroku/nodejs

対応2:rootに偽物のpackage.jsonとyarn.lockを作る
対応1をうまくこなすため、2つのファイルを作る。
package.jsonでenginesにnodeを指定。enginesでyarnを入れてもいいようですが、私はdependenciesでも大丈夫でした。

package.json
{
  "name": "rails-riot-webpacker",
  "description": "\"dummy package.json for heroku/nodejs buildpack support.\"",
  "engines":{
    "node": "6.5.0"
  },
  "dependencies": {
    "yarn": "0.19.1"
  }
}


yarn.lock
# Dummy yarn.lock to force heroku/nodejs to install yarn

対応3:Rakeタスクの追加
ここのをそのまま引用した。

lib/tasks/xxx.rb
Rake::Task['assets:precompile']
  .clear_prerequisites
  .enhance(['assets:compile_environment'])

namespace :assets do
  task compile_environment: [:yarn, :webpack] do
    Rake::Task['assets:environment'].invoke
  end

  desc 'Install node deps via yarn'

  task :yarn do
    sh 'bundle exec ./bin/yarn'
  end

  desc 'Compile assets with webpack'

  task :webpack do
    sh 'bundle exec rails webpacker:compile'
  end
end

最後に

役に立つかわかりませんが、step9まで実施した内容をここに公開しました。

7
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
5