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
のように書きます。
alert('hoge')
今回はわかりやすく alert
で hoge
と出力するだけのコードにしています。
webpack.configを開発用とproduction用を書く
開発時はHRMを行い、本番ではproduction用の設定でビルドしたいので今回は簡単に分けて書きます。
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をするため output
の publicPath
に公開されるURLを指定し、 devServer
の設定を追加しています。
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
を追加しています。 output
の filename
にハッシュ値付きの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に追加します。
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が違うのでそれを返すヘルパーを追記します。
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の中を書き換えてその書き換えた内容が出ればコンパイルは成功です。
ふがと書き換える。
まとめ
必要最低限ですが、Railsのフロントエンド開発をwebpackで出来るように構築しました。必要最低限しかやっていないのでここから先は割と自由に出来ると思います。
成果物のURLは以下です
https://github.com/nasum/app_name