2021-06-29 21:19

webpackerをインストールしてるrailsアプリで単純にassets:precompileを実行したい

webpackerをインストールしてるとassets:precompileでwebpackerの処理も動く。

単純にassets:precompileだけ動かしたかったので方法がないか調べた。

これでいけた。

rm bin/yarn
WEBPACKER_PRECOMPILE=false bin/rails assets:precompile

確認したバージョン:
  • rails 6.1.4
  • webpacker 5.4.0

以下調査ログ。

普通に実行してみる:

❯ bin/rails assets:precompile
yarn install v1.22.10
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 0.19s.
Compiling...
Compiled all packs in /Users/okonomi/src/local/rails-webpacker-sandbox/public/packs
Hash: e4cb1aa40fed2663ee2c
Version: webpack 4.46.0
Time: 446ms
Built at: 2021/06/29 21:03:08
                                        Asset       Size  Chunks                         Chunk Names
       js/application-c3e3aae48c4c321181e9.js   69.4 KiB       0  [emitted] [immutable]  application
    js/application-c3e3aae48c4c321181e9.js.br   15.4 KiB          [emitted]
    js/application-c3e3aae48c4c321181e9.js.gz   17.8 KiB          [emitted]
   js/application-c3e3aae48c4c321181e9.js.map    205 KiB       0  [emitted] [dev]        application
js/application-c3e3aae48c4c321181e9.js.map.br   43.8 KiB          [emitted]
js/application-c3e3aae48c4c321181e9.js.map.gz   50.9 KiB          [emitted]
                                manifest.json  364 bytes          [emitted]
                             manifest.json.br  133 bytes          [emitted]
                             manifest.json.gz  142 bytes          [emitted]
Entrypoint application = js/application-c3e3aae48c4c321181e9.js js/application-c3e3aae48c4c321181e9.js.map
[0] (webpack)/buildin/module.js 552 bytes {0} [built]
[4] ./app/javascript/packs/application.js 480 bytes {0} [built]
[5] ./app/javascript/channels/index.js 205 bytes {0} [built]
[6] ./app/javascript/channels sync _channel\.js$ 160 bytes {0} [built]
    + 3 hidden modules

yarn installのあとwebpack compileが動いてる。

どんなrakeタスクが動いてる確認する:

❯ bin/rails assets:precompile --trace
** Invoke assets:precompile (first_time)
** Invoke assets:environment (first_time)
** Execute assets:environment
** Invoke environment (first_time)
** Execute environment
** Invoke yarn:install (first_time)
** Execute yarn:install
yarn install v1.22.10
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 0.19s.
** Execute assets:precompile
** Invoke webpacker:compile (first_time)
** Invoke webpacker:verify_install (first_time)
** Invoke webpacker:check_node (first_time)
** Execute webpacker:check_node
** Invoke webpacker:check_yarn (first_time)
** Execute webpacker:check_yarn
** Invoke webpacker:check_binstubs (first_time)
** Execute webpacker:check_binstubs
** Execute webpacker:verify_install
** Invoke environment
** Execute webpacker:compile
Everything's up-to-date. Nothing to do

yarn:installとかwebpacker系のタスクが動いてる。

webpackerのタスクは環境変数でスキップできる。

https://github.com/rails/webpacker/blob/master/CHANGELOG.md#added-gem-1

❯ env WEBPACKER_PRECOMPILE=false bin/rails assets:precompile --trace
** Invoke assets:precompile (first_time)
** Invoke assets:environment (first_time)
** Execute assets:environment
** Invoke environment (first_time)
** Execute environment
** Invoke yarn:install (first_time)
** Execute yarn:install
yarn install v1.22.10
[1/4] 🔍  Resolving packages...
success Already up-to-date.
✨  Done in 0.19s.
** Execute assets:precompile

yarn:installがどこから呼ばれるのかソースコードを検索:

❯ grep -r "yarn:install" .bundle/ruby/3.0.0/gems
.bundle/ruby/3.0.0/gems/railties-6.1.4/lib/rails/tasks/yarn.rake:  Rake::Task["assets:precompile"].enhance [ "yarn:install" ]
.bundle/ruby/3.0.0/gems/webpacker-5.4.0/docs/engines.md:  # yarn:install was added in Rails 5.1
.bundle/ruby/3.0.0/gems/webpacker-5.4.0/lib/tasks/webpacker/compile.rake:  # yarn:install was added in Rails 5.1

railtiesのlib/rails/tasks/yarn.rakeを見る:

# Run Yarn prior to Sprockets assets precompilation, so dependencies are available for use.
if Rake::Task.task_defined?("assets:precompile") && File.exist?(Rails.root.join("bin", "yarn"))
  Rake::Task["assets:precompile"].enhance [ "yarn:install" ]
end

assets:precompileタスクが定義されているのとbin/yarnが存在する場合にyarn:installが呼ばれるようになってる。

bin/yarnを消してみる:

❯ rm bin/yarn
❯ WEBPACKER_PRECOMPILE=false bin/rails assets:precompile --trace
** Invoke assets:precompile (first_time)
** Invoke assets:environment (first_time)
** Execute assets:environment
** Invoke environment (first_time)
** Execute environment
** Execute assets:precompile

yarn:installが呼ばれなくなった!

まとめ

webpackerをインストールしてるrailsアプリで単純にassets:precompileだけ動かしたい場合は、以下のようにする:
  • bin/yarnを削除する
  • 環境変数WEBPACKER_PRECOMPILE=falseを設定する

備考

rails 6.0だとbin/yarnの存在チェックはなかった:

https://github.com/rails/rails/blob/6-0-stable/railties/lib/rails/tasks/yarn.rake
# Run Yarn prior to Sprockets assets precompilation, so dependencies are available for use.
if Rake::Task.task_defined?("assets:precompile")
  Rake::Task["assets:precompile"].enhance [ "yarn:install" ]
end