jsbundling-rails with Webpack
Webpacker利用してるRailsアプリからの移行を検討して試したメモ。
deeeki/rails_jsbundling_webpack
環境
- Rails 7.0.2.2
- jsbundling-rails 1.0.2 with Webpack 5.69.1
- Sass Vue TypeScript
app/javascript
にCSSも画像も入れる場合
仕組み
- jsbundling-rails(Webpack)が
app/javascript
からapp/assets/builds
に出力 - sprockets-railsが
app/assets/builds
から動的出力(dev)またはpublic/assets
に出力(prod) - Foreman経由でRailsサーバーとビルドウォッチャーを同時に動かす
bin/dev
が提供される
留意すること
2種類のビルドがあることでややこしくなっている。2022年3月時点でOpenなIssueもある。
ビルドスクリプトは手動追記
インストール後に促されるので、package.jsonに追記。
"scripts": { "build": "webpack --config webpack.config.js" }
Webpackでダイジェスト付加は不要
画像ファイルはShakapackerのルールを参考に、-[hash]
を無くす。
どのみちSprockets使うわけなので、最初から app/assets/images
に置くのがよさそう。
// webpack.config.js
module: {
rules: [
{
test: /\.(bmp|gif|jpe?g|png|tiff|ico|avif|webp|eot|otf|ttf|woff|woff2|svg)$/,
exclude: /\.(js|mjs|jsx|ts|tsx)$/,
type: 'asset/resource',
generator: {
filename: (pathData) => {
const folders = path.dirname(pathData.filename)
.replace('app/javascript/', '')
.split('/')
.slice(1)
const foldersWithStatic = path.join('static', ...folders)
return `${foldersWithStatic}/[name][ext][query]`
}
}
}
]
}
CSSでの画像パス
Sprockets Railsが置換してくれる(PR)。v3.3.0以降なので既存アプリで古い場合はバージョン上げる。
JSでの画像パス
本番でのダイジェスト付きパスを扱うには、Sprockets影響下で置換しないといけない。
<img src="<%= asset_path('static/image.png') %>" />
のように書き、Webpackは .js.erb
として出力。さらにSprocketsが適切なパスを出力。
// webpack.config.js
output: {
filename: "[name].js.erb"
},
Can't load images in JavaScript files · Issue #76 · rails/jsbundling-rails
全くきれいではないので、JSでは画像使わないのがよさそう(CSSで表示する)。
.js.erbの処理
jsbundling-railsが追記した状態の app/assets/config/manifest.js
ではうまくいかない。.js
と明記する。
-//= link_tree ../builds
+//= link_tree ../builds .js
Sprockets 4 has stopped working with js.erb? · Issue #667 · rails/sprockets
自動リロード
Foremanを活かし、webpack-dev-serverよりもguard-livereloadでViewファイルも対象にすると開発しやすい。
Rails 7: guard-livereload gemで開発中にライブリロードする|TechRacho by BPS株式会社
既存アプリのWebpackerからの移行選択肢
- Webpackerのまま様子見
- しばらくはこれでもいいかもしれない。Webpack5が使えない
- Shakapacker
- Webpackerの設定ファイルが使える。本家がリタイアしたことを考えるとどうか
- Simpacker
- 素のWebpackが使える。Webpackerと同名のヘルパーが用意されている
- jsbundling-rails
- 他のビルドツールへの移行もできる。本家が提供。現状はJSで画像扱いづらい
新規アプリでは
rails new
のデフォルトはimportmap-railsなので、JSの役割が少なければこちらを検討できるとよさそう。