启用 zeitwerk 后重新加载时未初始化的常量
uninitialized constant when reloading after enabling zeitwerk
从 Classic 迁移到 Zeitwerk 时遇到一些问题。
启用 zeitwerk 和 运行 rails s
后,一切似乎都正常。然后在保存 .rb 文件并刷新后,我在尝试从顶层 /lib
.
请求文件时看到“未初始化常量”错误
重新加载时配置错误,但我正在绞尽脑汁想弄清楚细节。我的印象是拥有顶级 /lib
文件夹很好并且使用 require
加载该目录中的文件与 Zeitwerk 兼容,但现在我不太确定......关于我哪里错了?
注意:我目前没有设置任何特定的 eager_load_paths
或 autoload_paths
编辑:更新了 @Xavier
建议的日志输出
Zeitwerk@rails.main: module CustomModule autovivified from directory *********/app/workers/custom_module
Zeitwerk@rails.main: autoload set for CustomModule::Profiler, to be loaded from *********/app/workers/custom_module/profiler.rb
Zeitwerk@rails.main: autoload set for CustomModule::AnotherProfiler, to be loaded from *********/app/workers/custom_module/another_profiler.rb
NameError - uninitialized constant CustomModule::AttributeParser
Did you mean? NameParserConstants:
app/models/user.rb:180:in `first_name'
app/middleware/catch_json_parse_errors.rb:8:in `call'
app/middleware/decompress_requests.rb:22:in `call'
命名空间 CustomModule
在项目中可重新加载的部分(在 app
下)和不可重新加载的部分(在 lib
下)共享。
这个不错,支持。您只需要仔细考虑加载优先级,因为如果 lib
定义了 CustomModule::Foo
并且 Rails 认为 CustomModule
是可重新加载的,那么在重新加载时没有人会再次加载 CustomModule::Foo
, require
是幂等的,所以 CustomModule::Foo
不会再被找到了。
解决方案是确保 lib
定义 命名空间,Rails 自动加载器 重新打开 它。与文档 here 基本相同。例如,这可以通过在从 lib
加载名称空间的初始化程序中发出 require
来完成。
这样,当自动加载器扫描文件系统时,它知道它不负责管理 CustomModule
。它会下降。如果有子常量,一切都会像往常一样工作,并且这些常量将被重新加载,但命名空间本身不会。
从 Classic 迁移到 Zeitwerk 时遇到一些问题。
启用 zeitwerk 和 运行 rails s
后,一切似乎都正常。然后在保存 .rb 文件并刷新后,我在尝试从顶层 /lib
.
重新加载时配置错误,但我正在绞尽脑汁想弄清楚细节。我的印象是拥有顶级 /lib
文件夹很好并且使用 require
加载该目录中的文件与 Zeitwerk 兼容,但现在我不太确定......关于我哪里错了?
注意:我目前没有设置任何特定的 eager_load_paths
或 autoload_paths
编辑:更新了 @Xavier
建议的日志输出Zeitwerk@rails.main: module CustomModule autovivified from directory *********/app/workers/custom_module
Zeitwerk@rails.main: autoload set for CustomModule::Profiler, to be loaded from *********/app/workers/custom_module/profiler.rb
Zeitwerk@rails.main: autoload set for CustomModule::AnotherProfiler, to be loaded from *********/app/workers/custom_module/another_profiler.rb
NameError - uninitialized constant CustomModule::AttributeParser
Did you mean? NameParserConstants:
app/models/user.rb:180:in `first_name'
app/middleware/catch_json_parse_errors.rb:8:in `call'
app/middleware/decompress_requests.rb:22:in `call'
命名空间 CustomModule
在项目中可重新加载的部分(在 app
下)和不可重新加载的部分(在 lib
下)共享。
这个不错,支持。您只需要仔细考虑加载优先级,因为如果 lib
定义了 CustomModule::Foo
并且 Rails 认为 CustomModule
是可重新加载的,那么在重新加载时没有人会再次加载 CustomModule::Foo
, require
是幂等的,所以 CustomModule::Foo
不会再被找到了。
解决方案是确保 lib
定义 命名空间,Rails 自动加载器 重新打开 它。与文档 here 基本相同。例如,这可以通过在从 lib
加载名称空间的初始化程序中发出 require
来完成。
这样,当自动加载器扫描文件系统时,它知道它不负责管理 CustomModule
。它会下降。如果有子常量,一切都会像往常一样工作,并且这些常量将被重新加载,但命名空间本身不会。