公式のドキュメントが現時点(2022/2/17)であまりイケていないため、実際に移行した際にとった手順を記録しておく。
なお、記述は省略しているが、最低でもステップごとに git commit
していくのがおすすめ。失敗したときに戻りやすい。
また、これはあくまで移行手順の一例であり、あらゆるプロジェクトに適用できるものではない。
-
webpacker を削除する
bundle remove webpacker bundle yarn remove @rails/webpacker
-
shakapacker をインストールする
bundle add shakapacker bundle install yarn add shakapacker
-
shakapacker のデフォルト設定を生成する
bin/rails webpacker:install
package.json をまるごと書き換えられてしまうので巻き戻して必要なパッケージだけ追加する
git checkout package.json yarn.lock yarn add @babel/core @babel/plugin-transform-runtime @babel/preset-env @babel/runtime babel-loader compression-webpack-plugin terser-webpack-plugin webpack webpack-assets-manifest webpack-cli webpack-merge yarn add -D webpack-dev-server
-
webpack.config.js を環境ごとの設定を読み込むよう修正する
const { env, webpackConfig } = require('shakapacker') const { existsSync } = require('fs') const { resolve } = require('path') const envSpecificConfig = () => { const path = resolve(__dirname, `${env.nodeEnv}.js`) if (existsSync(path)) { console.log(`Loading ENV specific webpack configuration file ${path}`) return require(path) } else { console.log(`WARNING: Using default webpack configuration. Did not find a Env specific file at path ${path}`) return webpackConfig } } module.exports = envSpecificConfig()
環境ごとの設定 (development.js, test.js, production.js) は以下のように書き換える。
const { webpackConfig } = require('shakapacker') // ここでカスタマイズ module.exports = webpackConfig
environment.js に書いていた共通の設定があれば webpack.config.js へ移動して、
envSpecificConfig()
とmerge
するとよい。environment.js は不要なので削除する。webpacker v5 から設定の API が変わっている。詳細は README を参照。
-
webpacker.yml の source_entry_path を元に戻す
default: &default source_path: app/javascript source_entry_path: packs
-
.browserslist の内容を package.json にコピーして、.browserslist を削除する
.browserslist の内容がdefaults
であれば、package.json に以下の記述を追加する。"browserslist": [ "defaults" ]
-
babel.config.js を削除して shakapacker が提供する babel 設定を使うよう package.json を修正する
package.json に以下を追加する。"babel": { "presets": [ "./node_modules/shakapacker/package/babel/preset.js" ] }
typescript については @babel/preset-typescript がインストールされていれば babel の設定もしてくれるようになってる。
react, vue を使っている場合など、shakapacker が提供する preset.js でカバーできない場合は自前で babel.config.js を持つ必要がある。 その場合は babel.config.js を消さず、公式ドキュメントを参考に babel.config.js を書き換える。
-
css, sass 用の設定をする
yarn add css-loader style-loader mini-css-extract-plugin css-minimizer-webpack-plugin sass sass-loader
webpack.config.js を修正する
const { env, webpackConfig, merge } = require('shakapacker') const { existsSync } = require('fs') const { resolve } = require('path') const cssConfig = { resolve: { extensions: ['.css', '.scss', '.sass'] } } const envSpecificConfig = () => { const path = resolve(__dirname, `${env.nodeEnv}.js`) if (existsSync(path)) { console.log(`Loading ENV specific webpack configuration file ${path}`) return require(path) } else { console.log(`WARNING: Using default webpack configuration. Did not find a Env specific file at path ${path}`) return webpackConfig } } module.exports = merge(envSpecificConfig(), cssConfig)
-
コンパイルが通るか試す
bin/webpacker bin/rails assets:clobber assets:precompile
-
古い binstub を削除する。呼び出してるスクリプトなどがあれば修正する
git rm bin/webpack bin/webpack-dev-server bin/webpack -> bin/webpacker bin/webpack-dev-server -> bin/webpacker-dev-server
-
webpacker.yml の source_entry_path を packs から / に変更する
wepbacker v5 時代のディレクトリ構成でコンパイルが通ることを確認したあとで、shakapacker デフォルトのディレクトリ構成に寄せるdefault: &default source_path: app/javascript source_entry_path: /
app/javascript/packs 配下のファイルを app/javascript に移動する。 相対パスで import してるコードがあれば修正する。
コンパイルが通るか確認する。
bin/webpacker
-
webpacker のヘルパーの呼び出しを修正する
stylesheet_pack_tag
,javascript_pack_tag
それぞれレイアウトごとに最大一回の呼び出しとなるようにする。
参考: https://github.com/shakacode/shakapacker#view-helpers -
画像のパスを修正する
asset_pack_path('media/images/hoge')
=>asset_pack_path('static/hoge')
参考: shakacode/shakapacker#65 -
軽く動かす
bin/rails s bin/webpacker-dev-server
-
テストが通るか確認する
bundle exec rspec
-
おつかれさまでした