Rails: Webpacker→jsbundling-rails+webpackアップグレード手順(翻訳)
本ガイドでは、Webpacker 5からjsbundling-rails + webpack 4への移行方法を手順を追って解説します。Webpacker/Shakapacker v6への移行方法については、Shakapackerのアップグレードガイドを参照してください。また、Webpackerとjsbundling-railsの比較についてはこちらをご覧ください。
なお、jsbundling-railsに移行すると、Webpackerの以下の機能は利用できなくなります。
上記の機能に依存している場合や、webpackのセットアップが複雑な場合は、以下のShakapackerへの移行を検討してください。
🔗 1. jsbundling-railsのセットアップ
最初にjsbundling-rails
をインストールします。
# Gemfileに以下を追加する
+ gem 'jsbundling-rails'
# コマンドラインでバンドルを再ビルドする
./bin/bundle install
# コマンドラインで基本設定を作成する
./bin/rails javascript:install:webpack
このインストールスクリプトでは以下が行われます。
- マニフェストにビルドを追加する
- gitのビルドを無視する
- マルチプロセス用に
foreman
をセットアップする ./webpack.config.js
を作成するpackage.json
にビルドスクリプトを追加する
🔗 webpackの設定を移動する
Webpackerとjsbundling-railsの差分を最小限にとどめたい場合は、以下を実行します。
- 1.
./webpack.config.js
を./config/webpack/
以下に移動する - 2.
package.json
の設定パスを以下のように変更する
- "build": "webpack --config ./webpack.config.js"
+ "build": "webpack --config ./config/webpack/webpack.config.js"
- 3.
webpack.config.js
の出力パスを以下のように変更する
- path: path.resolve(__dirname, "app/assets/builds"),
+ path: path.resolve(__dirname, '..', '..', 'app/assets/builds')
🔗 2. Webpackerを削除する
🔗 1. 以下のファイルを削除し、これらのファイルで行ったカスタマイズがすべて移行されていることを確認する
./bin/webpack
./bin/webpack-dev-server
./config/initializers/webpacker.rb
./config/webpacker.yml
./config/webpack/development.js
./config/webpack/environment.js
./config/webpack/production.js
./config/webpack/test.js
🔗 2. Webpackerのコンフィグを削除する
# config/initializers/assets.rbで以下を削除
-# Add Yarn node_modules folder to the asset load path.
-Rails.application.config.assets.paths << Rails.root.join('node_modules')
# config/initializers/content_security_policy.rbで以下を削除
-# # If you are using webpack-dev-server then specify webpack-dev-server host
-# policy.connect_src :self, :https, "http://localhost:3035", "ws://localhost:3035" if Rails.env.development?
🔗 3. Webpacker gemを削除する
# Gemfileで以下を削除
- gem 'webpacker'
🔗 4. ./bin/bundle install
を実行する
🔗 3. 依存関係をインストールする
Webpackerにはデフォルトで多数の依存関係がインストールされますが、jsbundling-railsの依存関係は開発者に任せられています。単にJavaScriptを変更せずに扱いたい場合、追加のパッケージをインストールする必要はありません。以後のセクションについては開発者の好みに応じて適用してください。
# CLIでWebpackerパッケージを削除する
yarn remove @rails/webpacker webpack-dev-server
🔗 オプション: Babel
Babelは、JavaScriptソースコードを古いバージョンのJavaScriptにトランスパイルするのに用いられます。
🔗 1. パッケージをインストールする
# Babelのプリセットをコマンドラインで追加する
yarn add @babel/core @babel/preset-env babel-loader
🔗 2. Babelを設定する
// package.jsonに以下を追加する
+ "babel": {
+ "presets": ["@babel/env"]
+ "presets": ["@babel/preset-env"]
+ }
🔗 3. webpackのローダーを利用する
// webpack.config.jsに以下を追加する
module.exports = {
module: {
rules: [
+ {
+ test: /\.(js)$/,
+ exclude: /node_modules/,
+ use: ['babel-loader'],
+ },
],
},
};
🔗 例: Babel + React + TypeScript
フロントエンドのフレームワークやTypeScriptはBabelでトランスパイルできます。この例では、ReactとTypeScriptを利用するセットアップを使います。
🔗 1. パッケージをインストールする
# Babelのプリセットをコマンドラインで追加する
yarn add @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript
🔗 2. Babelを設定する
// package.jsonに以下を追加する
+ "babel": {
+ "presets": [
+ "@babel/env",
+ "@babel/react",
+ "@babel/preset-env",
+ "@babel/preset-react",
+ "@babel/preset-typescript"
+ ]
+ }
🔗 3. webpackを設定する
// webpack.config.jsに以下を追加する
module.exports = {
module: {
rules: [
+ {
+ test: /\.(js|jsx|ts|tsx|)$/,
+ exclude: /node_modules/,
+ use: ['babel-loader'],
+ },
],
},
};
🔗 オプション: CSS + SASS
webpackでは、適切なローダーを使うことでCSSファイルを扱えるようになります。このセットアップでは、ファイルを扱うときにjsbundling-rails「のみ」を利用し、cssbundling-railsを利用していません。
🔗 1. パッケージをインストールする
# ローダー、プラグイン、node sassをコマンドラインでインストールする
yarn add css-loader sass sass-loader mini-css-extract-plugin webpack-remove-empty-scripts
🔗 2. webpackを設定する
// webpack.config.jsで以下を行う
// CSSを.cssファイルに切り出す
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
// CSSのみを含むエントリーから、exportされたJavaScriptファイルを削除する
// この例では、entry.customは対応する空のcustom.jsファイルを作成する
const RemoveEmptyScriptsPlugin = require('webpack-remove-empty-scripts');
module.exports = {
entry: {
// 自分のcssやsassのエントリをここに追加する
application: [
'./app/assets/javascripts/application.js',
'./app/assets/stylesheets/application.scss',
],
custom: './app/assets/stylesheets/custom.scss',
},
module: {
rules: [
// ローダーを含むCSS/SASS/SCSSルールをここに追加する
{
test: /\.(?:sa|sc|c)ss$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
],
},
resolve: {
// 追加のファイル種別をここに追加する
extensions: ['.js', '.jsx', '.scss', '.css'],
},
plugins: [
// プラグインをインクルードする
new RemoveEmptyScriptsPlugin(),
new MiniCssExtractPlugin(),
],
};
🔗 オプション: フォント、画像、SVG
webpackでは、適切なローダーを使うことでJavaScriptファイルやCSSファイル以外のファイルも扱えるようになります。このセットアップ手順は用途によって異なりますが、おおよそ以下のようになります。
🔗 1. パッケージをインストールする
yarn add file-loader
🔗 2. webpackを設定する
// webpack.config.jsに以下を追加する
module.exports = {
module: {
rules: [
+ {
+ test: /\.(png|jpe?g|gif|eot|woff2|woff|ttf|svg)$/i,
+ use: 'file-loader',
+ },
],
},
};
🔗 オプション: webpackでアセットをチャンクしてSprocketsで動作するようにする
Sprocketsが更新されて、アセットがフィンガープリント設定済みであることを検出した場合はフィンガープリントを再実行しないようになりました。これによって、webpackのcode splitting機能が利用可能になるとともに、すべてのアセットでキャッシュ無効化フィンガープリント(cache-busting fingerprints)が置かれるようになってCDNに保存可能になります。この設定によって、Sprocketsがエントリポイントファイルへのフィンガープリント設定を実行可能になり、javascript_include_tag
でそのアセット名を指定して読み込めるようになります。
// webpack.config.jsに以下を追加する:
module.exports = {
output: {
filename: "[name].js",
chunkFilename: "[name]-[contenthash].digested.js",
sourceMapFilename: "[file]-[fullhash].map",
path: path.resolve(__dirname, '..', '..', 'app/assets/builds'),
hashFunction: "sha256",
hashDigestLength: 64,
}
}
🔗 4. ビルドをテストする
webpackの設定が期待どおりに動作することを確認します。以下を実行することでバンドルを再ビルドできます。
yarn build --progress --color
エントリが複数ある場合は、個別のエントリごとに確認してから、最後にバンドル全体を確認することをおすすめします。
🔗 5. Webpackerのpackタグを置き換える
Webpackerのアセットタグを以下のように検索置換します。
# Webpackerのタグ # Sprocketsのタグ
javascript_pack_tag = javascript_include_tag
stylesheet_pack_tag = stylesheet_link_tag
タグの置き換えが完了すれば、アプリケーションはこれまでと同じように動くはずです。
🔗 オプション: development環境向けのサポートを追加する
jsbundling-railsはproductionモードにのみ同梱されています。以下のようにmode: 'development'
に切り替えることで、開発中のビルド時間を劇的に短縮できます。
// webpack.config.jsを以下のように変更する
+ const mode = process.env.NODE_ENV === 'development' ? 'development' : 'production';
module.exports = {
- mode: "production",
+ mode,
- devtool: "source-map",
…
+ optimization: {
+ moduleIds: 'deterministic',
+ }
}
概要
MITライセンスに基づいて翻訳・公開いたします。
表記の大文字小文字は「Webpacker」「Shakapacker」「webpack」「jsbundling-rails」「cssbundling-rails」に統一しました。