背景:
当我切换到Zeitwerk开发一个使用引擎(thredded)的rails 6.0应用程序时,我遇到了一些重载错误。我也是一个thredded的开发人员,所以在提交任何明显的修复之前,我想完全理解这一点:
我已经读过了:
- https://guides.rubyonrails.org/autoloading_and_reloading_constants
- https://guides.rubyonrails.org/engines.html#overriding-models-and-controllers (and implemented these fixes in the main app)
- https://github.com/fxn/zeitwerk/blob/main/README.md(信息量惊人)
- https://github.com/fxn/zeitwerk/issues/143
- 第一个问题(自动加载和引擎的分离)**:引擎是和主应用程序在同一个zeitwerk示例/加载器中自动加载的,还是它们以某种方式单独加载的?也就是说,用
Rails.application.reloader.to_prepare do
Package 一些代码是否能确保在主应用程序和引擎重新加载之前运行代码。
- 第一个问题(自动加载和引擎的分离)**:引擎是和主应用程序在同一个zeitwerk示例/加载器中自动加载的,还是它们以某种方式单独加载的?也就是说,用
- 第二个问题(重新加载引擎代码)**:当主应用程序重新加载时,引擎的常量是否重新加载?(我的理解是肯定的)。
- 第三个问题(配置引擎)**:目前Threded的文档建议Threded的配置发生在一个初始化器中--例如
Thredded.some_configuration_option = value
--但是我认为这会被自动加载擦除?因此可能需要用(我认为)Rails.application.reloader.to_prepare do
Package (但是这不是例如Devise推荐的(参见https://github.com/heartcombo/devise/blob/main/lib/generators/templates/devise.rb),并且似乎与https://github.com/fxn/zeitwerk/issues/143冲突)。
- 第三个问题(配置引擎)**:目前Threded的文档建议Threded的配置发生在一个初始化器中--例如
- 第四个问题(所有这些都要准备)**:有人能解释一下或给我指一下澄清以下两种产品生命周期差异的文档吗?
Rails.application.reloader.to_prepare do
(并且块是否至少运行一次,即使它在生产环境中急于加载并启用了重新加载)Rails.application.config.to_prepare do
SomeEngine::Engine.config.to_prepare do
任何答案都很好。有点长的Q,有多个部分。如果合适的话,我很乐意把它分成多个StackOverflow Q,但它们看起来很有联系。
1条答案
按热度按时间mwg9r5ms1#
根据上面评论中的讨论和https://github.com/fxn/zeitwerk/issues/240中的讨论回答我对未来的问题。
(1)是的,主自动加载器同时管理应用程序和所有引擎。
(2)是的,当主应用程序重新加载时,引擎的常量也会重新加载。
(3)默认情况下,仅自动加载引擎的app目录中的内容(除非在engines engine.rb中更改config.autoload_paths),并且引擎的顶级常量(在本例中为
Thredded
模块)通常在app外部的lib中定义(例如lib/thredded.rb)。(4)大致确定的答案(如有任何更新,欢迎提供)
(See https://guides.rubyonrails.org/engines.html#separate-assets-and-precompiling获取此初始值设定项方法的示例)
我发现当一个引擎想要修补另一个引擎时,这对于定义“覆盖”特别有用:
这与您在主应用中对引擎中自动加载的常量进行monkey-patching时所做的操作类似(https://guides.rubyonrails.org/engines.html#overriding-models-and-controllers)。