Zeitwerk:将引擎/宝石目录添加到父母铁路应用程序的自动加载路径
我正在尝试在现有的旧宝石(Rails ::引擎)中切换到Zeitwerk。到目前为止,所有文件均已手动需要
d和自动加载
ed。再加上引擎的LIB折叠器通过config.autoload_paths +=路径[“ lib”]。to_a
in 类myEngine< Rails ::引擎
。
使用Zeitwerk的开关通过 readme :
require "zeitwerk"
loader = Zeitwerk::Loader.for_gem
.
. --> more project specific stuff here
.
loader.setup # ready!
太好了!现在,我想在Rails应用程序中使用GEM,然后将发动机的目录添加到Rails应用程序的AutoLoad_Path中。以前通过上述config.autoload_paths
进行了正常工作。如果我现在这样做,则会失败以下错误消息:
Zeitwerk::Error:
loader
#<Zeitwerk::Loader:0x00000001094d4bd0
...
wants to manage directory /gems/<NameOfGem>/lib, which is already managed by
#<Zeitwerk::Loader:0x0000000106b2d728
...
将引擎的LIB目录添加到Rails应用程序的自动加载路径中的正确方法是什么?
谢谢你!
I'm trying to switch to Zeitwerk in an existing, older Gem (Rails::Engine). Until now all files have been manually require
d and autoload
ed. Plus the engine's lib-folder was added to autoload_paths via config.autoload_paths += paths["lib"].to_a
in class MyEngine < Rails::Engine
.
The switch to use Zeitwerk worked fine via the described way on the Readme:
require "zeitwerk"
loader = Zeitwerk::Loader.for_gem
.
. --> more project specific stuff here
.
loader.setup # ready!
So far so good! Now I want to use the Gem in a Rails app and add the engine's directories to the autoload_path of the Rails application. This worked fine previously via the above mentioned config.autoload_paths
. If I do this now, it fails with the following error message:
Zeitwerk::Error:
loader
#<Zeitwerk::Loader:0x00000001094d4bd0
...
wants to manage directory /gems/<NameOfGem>/lib, which is already managed by
#<Zeitwerk::Loader:0x0000000106b2d728
...
What is the correct way to add the engine's lib-directories to the autoload path of the Rails application?
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
rails 设置两个加载程序
main
and 一旦:这些只是
zeitwerk :: Loader
的实例。 rails 还为您提供了一个配置,将根目录添加到这些加载程序中:当Gem的
lib
目录通过以下一种配置之一添加到自动加载到AutoLoad, lib 成为根目录:当称为GEM的类时, zeitwerk 使用注册的加载程序查找并加载与此类相对应的文件。
如果GEM然后设置自己的加载程序:
zeitwerk :: Loader
的另一个实例是用自己的根目录创建的:zeitwerk 不允许两个加载程序具有共享目录并提出一个错误,显示两个冲突的装载机。
因为宝石是a rails :: Engine 最好的选择是让 rails manage zeitwerk 加载器,然后删除 zeitwerk :: loader。 for_gem 设置。
另一方面,已经设置了GEM Loader,并且不需要 config.autoload_paths 。
更新
zeitwerk 进行加载和重新加载。 rails 在这里只是另一个宝石。
如果您不使用Rails Config,则 zeitwerk 将通过
zeitwerk :: gemloader(@tag = my_engine)
找到文件。如果您使用Rails Config, Zeitwerk 将通过
Zeitwerk :: Loader(@tag = rails.main)
找到文件(Make Gemloader如果 lib 是任何现有加载程序中的根目录,则无需在 lib 目录中具有任何需要或自动加载文件。除了在 zeitwerk 启动之前需要的东西,例如 myEngine ::引擎 from lib/my_engine/Engine.rb 。
Rails sets up two loaders
main
andonce
:These are just instances of
Zeitwerk::Loader
. Rails also gives you a config to add root directories to these loaders:When gem's
lib
directory is added to autoload through one of these configs, lib becomes a root directory:When a class from the gem is called, zeitwerk uses registered loaders to look up and to load the file corresponding to this class.
If the gem then sets up its own loader:
another instance of
Zeitwerk::Loader
is created with its own root directories:Zeitwerk doesn't allow two loaders to have a shared directory and raises an error showing two conflicting loaders.
Because the gem is a Rails::Engine the best option is to let rails manage zeitwerk loaders and remove Zeitwerk::Loader.for_gem setup.
On the other hand, gem loader is already set up and config.autoload_paths is not needed.
Update
Zeitwerk does the loading and reloading. Rails is just another gem here.
If you don't use rails config, Zeitwerk will find files through
Zeitwerk::GemLoader(@tag=my_engine)
, that the gem has created.If you use rails config, Zeitwerk will find files through
Zeitwerk::Loader(@tag=rails.main)
, that rails has created (making GemLoader unnecessary).If lib is a root directory in any of the existing loaders there is no need to have any requires or autoloads for files in lib directory. Except for things that are needed before Zeitwerk kicks in, like MyEngine::Engine from lib/my_engine/engine.rb.