Search code examples
ruby-on-railsrails-engineszeitwerk

Questions about Reloading and Engines in rails with Zeitwerk autoloader


Background:

I am getting some reloading errors in development when switching to Zeitwerk for a rails 6.0 application that uses an engine (thredded). I'm also a developer on thredded, so want to understand this fully before committing any apparent fixes:

I've already read:

First Question (separation of autoloading and engines): Are engines autoloaded in the same zeitwerk instance/loader as the main app, or are they somehow loaded separately? That is to say does wrapping some code with Rails.application.reloader.to_prepare do ensure that code is run before both the main app and the engine are reloaded.

Second Question (engine code reloading): Are engine's constants reloaded when the main app reloads? (my understanding is yes).

Third Question (configuring engines): Currently Thredded's docs suggest that the configuration of Thredded happens in an initializer -- e.g. Thredded.some_configuration_option = value - but I think that would get wiped away with autoloading? So therefore probably needs to be wrapped with (I think) Rails.application.reloader.to_prepare do (but this isn't what e.g. Devise recommends (see https://github.com/heartcombo/devise/blob/main/lib/generators/templates/devise.rb) and seems to conflict with https://github.com/fxn/zeitwerk/issues/143). What have I misunderstood here?

Fourth Question (all these to_prepares): Can someone explain or point me to docs that clarify the lifecycle difference between:

  • Rails.application.reloader.to_prepare do (and is the block run at least once even when it is eager loaded in production with reloading on)
  • Rails.application.config.to_prepare do
  • SomeEngine::Engine.config.to_prepare do

Any answers would be great. Kind of a long Q with multiple parts. Happy to split this into multiple StackOverflow Qs if appropriate but they seem quite linked.


Solution

  • Answering my question for the future based on the discussion in comments above and the discussion in https://github.com/fxn/zeitwerk/issues/240.

    (1) Yes, the main autoloader manages both the application and all engines.

    (2) Yes, engine's constants are reloaded when the main app reloads.

    (3) By default only what is in the engine's app directory is autoloaded (unless config.autoload_paths is changed in for example the engines engine.rb) and the engine's top-level constant (in this case the Thredded module) is typically defined outside of app, in lib (e.g. lib/thredded.rb).

    (4) approximately definitive answers (any updates appreciated)