即将发布的 Rails 7 代表了自动加载的里程碑。
即将进行两项重要更改
Zeitwerk 已成为默认的自动加载器,已持续两年多。Rails 6.0 和 Rails 6.1 支持 zeitwerk
和 classic
模式以帮助项目过渡。此阶段将在 Rails 7 结束:classic
模式将不再可用。
如果使用 to_prepare
进行封装,则初始化器可以自动加载可重新加载常量,但除此之外不可以。
您的 6.x 应用程序或许已为这些更改做好准备。否则,您可以提前做好准备以简化升级。我们来简单了解一下这些更改的影响。
zeitwerk
模式下运行仍在以 classic
模式运行的应用程序必须切换到 zeitwerk
模式。
别担心,许多非平凡的 Rails 应用程序报告了非常平稳的切换。您很可能只需要切换开关,也许配置一些屈折器,就可以了。请查看Rails 6.0 升级指南了解更多详情。
如果您发现任何意外情况,我个人非常愿意提供帮助,只需开启一个问题并标记@fxn。
在 Rails 7 中,没有可设置自动加载模式的配置点,,config.autoloader=
已被删除。
您不宣布对内部 API 进行更改,但由于 classic
自 Rails 首次发布以来就存在,因此值得在这篇文章中进行介绍。
ActiveSupport::Dependencies
实现 classic
自动加载器,并且由于删除了它,许多内部方法已级联删除,例如 hook!
、unhook!
、depend_on
、require_or_load
、mechanism
、qualified_name_for
、warnings_on_first_load
、logger
、verbose
以及其他许多方法。
辅助内部类或模块也不见了,例如 Reference
、ClassCache
、ModuleConstMissing
、Blamable
等等。
大约 90% 的 active_support/dependencies.rb
已被删除。可以将 edge 中的版本 与 6.1 中的版本 进行比较。
在 Rails 6.0 之后,在 to_prepare
块之外的初始化期间自动加载可重新加载的常量时,这些常量会被卸载,并且会发出此警告。
DEPRECATION WARNING: Initialization autoloaded the constant User.
Being able to do this is deprecated. Autoloading during initialization is going
to be an error condition in future versions of Rails.
Reloading does not reboot the application, and therefore code executed during
initialization does not run again. So, if you reload User, for example,
the expected changes won't be reflected in that stale Class object.
This autoloaded constant has been unloaded.
In order to autoload safely at boot time, please wrap your code in a reloader
callback this way:
Rails.application.reloader.to_prepare do
# Autoload classes and modules needed at boot time here.
end
That block runs when the application boots, and every time there is a reload.
For historical reasons, it may run twice, so it has to be idempotent.
Check the "Autoloading and Reloading Constants" guide to learn more about how
Rails autoloads and reloads.
(called from ...)
如果您仍然收到此警告,请查阅 自动加载指南 中关于在应用程序启动时自动加载的部分。否则,您将在 Rails 7 中收到 NameError
。
想支持 Rails 6.x 的引擎可以检查
Rails.autoloaders.zeitwerk_enabled?
以了解父应用程序是否在 zeitwerk
模式下运行。在 Rails 7 中此谓词仍然存在,可用于此用例。