有一种程序化的方法可以检测Zeitwerk::NameError when upgrading to Rails6



我目前正在将一个旧的Rails应用程序迁移到Rails6。

项目中的某些文件似乎与其中定义的类不一致。在运行应用程序的测试时,我没有看到这个错误,但在部署后,我收到了如下错误:

Zeitwerk::NameError: expected file /app/my?_/app/lib/multi_io.rb to define constant MultiIo, but didn't

在之前的SO问题中,我可以找到以下建议:

  • Rails 6:Zeitwerk::NameError dos';t从模块集config.autoloader = :classic加载类
  • 如何在Zeitwerk for Rails6中忽略文件夹?忽略给定的路径
  • Rails6微调config.autoload_path中的自动加载和Zeitwerk模式

我没有寻找解决方法,所以我更正了引发异常的文件。

我想找到一种程序化的方法来检测所有不一致的路径/类名,而无需在生产模式下运行应用程序。

到目前为止,我想到了三个选择:

  1. 用于验证自动加载的rake任务(gem不提供(。它存在吗?您会在开发环境中从rails控制台运行一个代码片段吗
  2. rubocop-cop或其他静态代码分析器。有吗
  3. 在测试环境中强制加载

在不需要多次迭代/部署的情况下验证代码的建议方法是什么?

提前非常感谢

您可以检查项目与zeitwerk::check任务的自动加载兼容性:

$ bin/rails zeitwerk:check
Hold on, I am eager loading the application.
All is good!

它练习所有的自动加载路径,并将标记问题,例如由常量名称推断中的更改引起的问题(例如使用缩写词的问题(。除了在升级指南中,该任务似乎没有被广泛宣传或记录。但是,实际上,我有时会使用它来解决项目中经常出现的命名问题(即,类与文件不匹配的地方(。

@rmlockerd在这里的回答中描述了最好的工具之一bin/rails zeitwerk:check

我发现其他提供信息的文章有:

  • 在Rails中理解Zeitwerk
  • 9个提示;帮助您在Rails应用程序
  • 关于自动加载的Rails文档
  • 关于从Rails 5.2升级到6.0的Rails文档

我所做的过程是运行bin/rails zeitwerk:check修复一个错误,再次运行它,直到我看到";一切都很好;。之后,我们的规范测试报告了错误。

需要解决的一个常见问题是,如果文件夹不在Rails默认文件结构中,Zeitwerk在自动加载时将无法找到它。我们有一个名为";服务";(app/services(,需要添加到application.rb文件中的自动加载路径中,如:

config.autoload_paths += %W(#{config.root}/app/services/)

错误:

需要文件path/file_name.rb来定义常量FileName

修复:删除引用类定义位置的其他文件中的任何requirerequire_relative(Zeitwerk不需要它们(。

错误(类在子目录的模块中定义(:

名称错误:未初始化常量子文件::ClassName

修复:

另一个S/O答案中有详细说明。每当在子文件夹结构中使用方法时,调用为Folder::SubDirectory::Class.method_call

祝你好运!

相关内容

最新更新