From 9b61af817911849d92aa5d3c7d9e0eabe651a47c Mon Sep 17 00:00:00 2001 From: Xavier Noria Date: Wed, 5 Jan 2022 12:59:49 +0100 Subject: [PATCH] Delay loading Zeitwerk --- railties/lib/rails.rb | 3 +- railties/lib/rails/application.rb | 5 +- railties/lib/rails/application/finisher.rb | 1 - railties/lib/rails/autoloaders.rb | 64 +++++++++++---------- railties/lib/rails/autoloaders/inflector.rb | 22 +++---- 5 files changed, 48 insertions(+), 47 deletions(-) diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb index 8677d12adb..b2647bdbc2 100644 --- a/railties/lib/rails.rb +++ b/railties/lib/rails.rb @@ -12,7 +12,6 @@ require "active_support/core_ext/object/blank" require "rails/application" require "rails/version" -require "rails/autoloaders" require "active_support/railtie" require "action_dispatch/railtie" @@ -115,7 +114,7 @@ module Rails end def autoloaders - Autoloaders + application.autoloaders end end end diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index b0dd97b0a0..43dc1ccfed 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -10,6 +10,7 @@ require "active_support/hash_with_indifferent_access" require "active_support/configuration_file" require "rails/engine" require "rails/secrets" +require "rails/autoloaders" module Rails # An Engine with the responsibility of coordinating the whole boot process. @@ -95,7 +96,7 @@ module Rails attr_accessor :assets, :sandbox alias_method :sandbox?, :sandbox - attr_reader :reloaders, :reloader, :executor + attr_reader :reloaders, :reloader, :executor, :autoloaders delegate :default_url_options, :default_url_options=, to: :routes @@ -117,6 +118,8 @@ module Rails @reloader = Class.new(ActiveSupport::Reloader) @reloader.executor = @executor + @autoloaders = Rails::Autoloaders.new + # are these actually used? @initial_variable_values = initial_variable_values @block = block diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb index 036b384c3a..96c85dcd3e 100644 --- a/railties/lib/rails/application/finisher.rb +++ b/railties/lib/rails/application/finisher.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -require "zeitwerk" require "active_support/core_ext/string/inflections" require "active_support/core_ext/array/conversions" require "active_support/descendants_tracker" diff --git a/railties/lib/rails/autoloaders.rb b/railties/lib/rails/autoloaders.rb index c7c6550469..1aba548d1d 100644 --- a/railties/lib/rails/autoloaders.rb +++ b/railties/lib/rails/autoloaders.rb @@ -1,44 +1,48 @@ # frozen_string_literal: true -require "zeitwerk" - module Rails - module Autoloaders # :nodoc: + class Autoloaders # :nodoc: require_relative "autoloaders/inflector" - class << self - include Enumerable + include Enumerable - def main - @main ||= Zeitwerk::Loader.new.tap do |loader| - loader.tag = "rails.main" - loader.inflector = Inflector - end - end + attr_reader :main, :once - def once - @once ||= Zeitwerk::Loader.new.tap do |loader| - loader.tag = "rails.once" - loader.inflector = Inflector - end - end + def initialize + # This `require` delays loading the library on purpose. + # + # In Rails 7.0.0, railties/lib/rails.rb loaded Zeitwerk as a side-effect, + # but a couple of edge cases related to Bundler and Bootsnap showed up. + # They had to do with order of decoration of `Kernel#require`, something + # the three of them do. + # + # Delaying this `require` up to this point is a convenient trade-off. + require "zeitwerk" - def each - yield main - yield once - end + @main = Zeitwerk::Loader.new + @main.tag = "rails.main" + @main.inflector = Inflector - def logger=(logger) - each { |loader| loader.logger = logger } - end + @once = Zeitwerk::Loader.new + @once.tag = "rails.once" + @once.inflector = Inflector + end - def log! - each(&:log!) - end + def each + yield main + yield once + end - def zeitwerk_enabled? - true - end + def logger=(logger) + each { |loader| loader.logger = logger } + end + + def log! + each(&:log!) + end + + def zeitwerk_enabled? + true end end end diff --git a/railties/lib/rails/autoloaders/inflector.rb b/railties/lib/rails/autoloaders/inflector.rb index c79c1bac66..6c89757034 100644 --- a/railties/lib/rails/autoloaders/inflector.rb +++ b/railties/lib/rails/autoloaders/inflector.rb @@ -2,20 +2,16 @@ require "active_support/inflector" -module Rails - module Autoloaders - module Inflector # :nodoc: - # Concurrent::Map is not needed. This is a private class, and overrides - # must be defined while the application boots. - @overrides = {} +module Rails::Autoloaders::Inflector # :nodoc: + # Concurrent::Map is not needed. This is a private class, and overrides + # must be defined while the application boots. + @overrides = {} - def self.camelize(basename, _abspath) - @overrides[basename] || basename.camelize - end + def self.camelize(basename, _abspath) + @overrides[basename] || basename.camelize + end - def self.inflect(overrides) - @overrides.merge!(overrides) - end - end + def self.inflect(overrides) + @overrides.merge!(overrides) end end