タイトルどおりRailsのフロントエンド環境をwebpackにしました。
前提
- Rails 5.2.1
- 開発はdockerを使ってる
- 既存はSprocketsを使ってる
- 本番はAWSで稼働してる
- deployにはcapistranoを使用している
対応方針
基本はこれをほぼパクった(本当に感謝してます)
deployのことを考えるとSprocketsのいいところを残しつつ、JS周りをnpmに寄せるのが良さそうかと思いました。
なるべくgem依存をなくしたかったので、webpackerも使っておらずwebpackだけです。
参考にした記事とはwebpackのバージョンが恐らく変わってるのでその辺の書き方だけ補足しておきます。
css周りは特にいじってないのでそのままです。
app/assets/stylesheets以下にscssで書いてるのを配信
foremanは今の所使ってないが、必要になったら使う予定
webpackの設定
- webpack 4.39
- webpack-cli 3.3.6
frontend/config/webpack.config.js
webpack = require('webpack')
const path = require('path')
// Sprocketsを使わずにwebpackだけでやるなら、hashをつける
// let fileName = argv.mode == 'development' ? '[name].js' : '[name]-[hash].js';
module.exports = (env, argv) => {
return {
entry: {
application: './src/javascripts/application.js',
},
output: {
path: path.resolve(__dirname, '../../app/assets/javascripts'),
filename: [name].js
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
options: {
presets: [
"@babel/preset-env"
]
}
}
]
},
]
},
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
]
}
}
また、package.jsonのscriptsの書き方も変えました。
frontend/package.json
"scripts": {
"release": "webpack --mode production --config config/webpack.config.js",
"build": "webpack --mode development --devtool inline-source-map --open --config config/webpack.config.js",
"watch": "webpack --mode development --devtool inline-source-map --watch --config config/webpack.config.js"
},
あとはapplication.jsをいい感じに修正を加えます
frontend/src/javascripts/application.js
import * as jquery from 'jquery';
global.$ = jquery;
import Rails from 'rails-ujs';
Rails.start();
import * as ActiveStorage from 'activestorage';
ActiveStorage.start();
import 'bootstrap';
import 'popper.js';
import './hogehoge.js'; // 自作のjs
一応これで動いたんですが、デプロイ時にエラーになりました。
参考記事通りに .gitignoreに/app/assets/javascriptsを入れたことで、capistranoで以下のようなエラーが出ました。
Sprockets::ArgumentError: link_directory argument must be a directory
javascriptsのフォルダ自体は消すとダメだと思い以下のように修正したら動きました。
- /app/assets/javascripts
+ app/assets/javascript/*.js