LoginSignup
14
11

More than 5 years have passed since last update.

RailsでSprocketsを使わないでwebpackを使いHMRで開発する

Last updated at Posted at 2017-05-25

RailsでSprocketsを使わずwebpackを使って開発するために、必要最低限のやることをまとめます。ついでにHMRが出来るようにして開発時の利便性を高めます(必要最低限じゃなかったのか)。

ここから先は順を追って実装すれば環境が整うように書いていきます。

使っている代表的ソフトウェアのバージョン。

ソフトウェア バージョン
Rails 5.1.1
webpack 2.6.1
webpack-dev-server 2.4.5

RailsのプロジェクトをSprocketsなしで作成する

まずは rails new を実行します。

$ rails new app_name --skip-sprockets --skip-javascript

--skip-sprockets でSprocketsを無くし、 --skip-javascript でJavaScriptの読み込みを無くします

必要なJavaScriptのパッケージをインストールする

必要なJavaScriptのパッケージをインストールします。

$ yarn add -D webpack webpack-dev-server webpack-manifest-plugin

必要最低限のパッケージをまずはインストールします。

frontendディレクトリにJSを配置する

ビルド対象のJSを frontend/src/index.js のように書きます。

index.js
alert('hoge')

今回はわかりやすく alerthoge と出力するだけのコードにしています。

webpack.configを開発用とproduction用を書く

開発時はHRMを行い、本番ではproduction用の設定でビルドしたいので今回は簡単に分けて書きます。

webpack.config.dev.js
const webpack = require('webpack')
const path = require('path')
const ManifestPlugin = require('webpack-manifest-plugin')

module.exports = {
  entry: {
    index: path.resolve(__dirname, 'frontend/src/index.js')
  },
  output: {
    path: path.resolve(__dirname, 'public/dist'),
    filename: '[name].js',
    publicPath: 'http://localhost:8080/'
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify(process.env.NODE_ENV),
      },
    }),
  ],
  devServer: {
    headers: { 'Access-Control-Allow-Origin': '*' },
    contentBase: 'public/dist',
  },
}

開発用の webpack.config です。HMRをするため outputpublicPath に公開されるURLを指定し、 devServer の設定を追加しています。

webpack.config.prod.js
const webpack = require('webpack')
const path = require('path')
const ManifestPlugin = require('webpack-manifest-plugin')

module.exports = {
  entry: {
    index: path.resolve(__dirname, 'frontend/src/index.js')
  },
  output: {
    path: path.resolve(__dirname, 'public/dist'),
    filename: '[name]-[hash].js'
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify(process.env.NODE_ENV),
      },
    }),
    new webpack.optimize.UglifyJsPlugin({
      minimize: true,
      compress: {
        warnings: false,
      },
    }),
    new ManifestPlugin(),
  ],
}

Production用のmanifestをはき出すため、 ManifestPluginを追加しています。 outputfilename にハッシュ値付きのJSをはき出すように設定しています。

package.jsonのscriptsに実行スクリプトを書く

package.json にproductionビルド用と開発用のスクリプトを書きます。

"scripts": {
    "build": "NODE_ENV=production webpack --config webpack.config.prod.js --progress --colors",
    "dev": "NODE_ENV=development webpack-dev-server --config webpack.config.dev.js --progress --colors --inline --hot"
}

manifest.jsonの場所をRailsの設定に追加する

production環境ではハッシュ値付きのJSの場所を manifest.json から特定する必要があるので、webpackではき出された manifest.json を読み込ませるようにinitializerに追加します。

manifest.rb
if File.exist?(Rails.root.join('public', 'dist', 'manifest.json'))
  Rails.application.config.assets_manifest = JSON.parse(File.read(Rails.root.join('public', 'dist', 'manifest.json')))
end

JavaScriptのパスを返すヘルパーの作成

productionと開発で読み込ませるJSが違うのでそれを返すヘルパーを追記します。

application_helper.rb
module ApplicationHelper
  def assets_path(path)
    return "http://localhost:8080/#{path}" if Rails.env.development?
    manifest = Rails.application.config.assets_manifest
    path = manifest[path] if manifest && manifest[path].present?
    "/dist/#{path}"
  end
end

使い方としては以下のようにscriptタグのsrcの中で使用します。

<script type="text/javascript" src="<%= assets_path('index.js') %>"></script>

実行

webpack-dev-server を起動します。

$ yarn run dev

コンパイルされ以下のように結果が得られ、alertの中を書き換えてその書き換えた内容が出ればコンパイルは成功です。

image.png

ふがと書き換える。

image.png

まとめ

必要最低限ですが、Railsのフロントエンド開発をwebpackで出来るように構築しました。必要最低限しかやっていないのでここから先は割と自由に出来ると思います。

成果物のURLは以下です
https://github.com/nasum/app_name

参考URL

Rails + モダンJS環境(Webpack)で新規アプリ作成 - Qiita

webpack-dev-serverの基本的な使い方とポイント - dackdive's blog

14
11
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
14
11