Frage Rails 5: Lade lib Dateien in der Produktion


Ich habe eine meiner Apps von Rails 4.2.6 auf Rails 5.0.0 aktualisiert. Das Upgrade-Anleitung sagt, dass die Autoload-Funktion in der Produktion standardmäßig deaktiviert ist.

Jetzt erhalte ich immer einen Fehler auf meinem Produktionsserver, da ich alle lib Dateien mit Autoload in den geladen habe application.rb Datei.

module MyApp
    class Application < Rails::Application
        config.autoload_paths += %W( lib/ )
    end
end

Für jetzt habe ich das eingestellt config.enable_dependency_loading zu true aber ich frage mich, ob es eine bessere Lösung dafür gibt. Es muss einen Grund geben, dass Autoloading standardmäßig in der Produktion deaktiviert ist.


75
2017-07-05 08:30


Ursprung


Antworten:


Meine Liste der Änderungen nach dem Umzug nach Rails 5:

  1. Ort lib dir in app weil alles Code in App ist automatisch geladen in dev und eifrig geladen in prod und am wichtigsten ist Autoreloaded In der Entwicklung müssen Sie den Server nicht jedes Mal neu starten, wenn Sie Änderungen vornehmen.
  2. Entfernen Sie alle require Anweisungen, die auf Ihre eigenen Klassen verweisen lib weil sie sowieso alle automatisch geladen werden, wenn ihre Datei- / Verzeichnisnamen korrekt sind und wenn Sie gehen require Statements kann es Autoreloading brechen. Mehr Info Hier
  3. einstellen config.eager_load = true in allen Umgebungen, um Code-Ladeprobleme eifrig in Dev zu sehen.
  4. Benutzen Rails.application.eager_load! bevor Sie mit Threads spielen, um "Circular Dependency" -Fehler zu vermeiden.
  5. Wenn Sie irgendwelche Ruby / Rails Erweiterungen haben, dann lassen Sie diesen Code in alt lib Verzeichnis und laden Sie sie manuell vom Initialisierer. Dies stellt sicher, dass Erweiterungen vor Ihrer weiteren Logik geladen werden, die davon abhängen kann:

    # config/initializers/extensions.rb
    Dir["#{Rails.root}/lib/ruby_ext/*.rb"].each { |file| require file }
    Dir["#{Rails.root}/lib/rails_ext/*.rb"].each { |file| require file }
    

105
2017-10-13 10:58



Ich habe es gerade benutzt config.eager_load_paths Anstatt von config.autoload_paths Wie erwähnt Akostadinov auf GitHub Kommentar: https://github.com/rails/rails/issues/13142#issuecomment-275492070

# config.autoload_paths << Rails.root.join('lib')
config.eager_load_paths << Rails.root.join('lib')

Es arbeitet auf der Entwicklungs- und Produktionsumgebung.

Vielen Dank Johan um einen Vorschlag zu ersetzen #{Rails.root}/lib mit Rails.root.join('lib')!


32
2017-07-08 11:32



Autoloading ist in der Produktionsumgebung aufgrund der Thread-Sicherheit deaktiviert. Vielen Dank an @ Зелёный für den Link.

Ich löste dieses Problem, indem ich die lib-Dateien in einem speicherte lib Ordner in meinem app Verzeichnis wie empfohlen auf Github. Jeder Ordner in der app Ordner wird automatisch von Rails geladen.


24
2017-08-18 17:34



Es muss einen Grund geben, dass Autoloading in der Produktion durch deaktiviert ist   Standard.

Hier ist eine lange Diskussion über dieses Thema. https://github.com/rails/rails/issues/13142


17
2017-07-05 08:43



Dies ermöglicht eine automatische Autoreload-Funktion und funktioniert auch in der Produktionsumgebung.

P.S. Ich habe meine Antwort geändert, jetzt fügt sie beiden, unabhängig von der Umgebung, Autoload-Pfade hinzu, um auch in benutzerdefinierten Umgebungen arbeiten zu können (wie in der Phase).

# config/initializers/load_lib.rb
...
config.eager_load_paths << Rails.root.join('lib')
config.autoload_paths << Rails.root.join('lib')
...

5
2018-01-29 13:50



Für jeden, der damit zu kämpfen hat, reicht es nicht, einfach ein Verzeichnis darunter zu legen app/. Ja, Sie erhalten Autoloading, aber nicht notwendig Neuladen, das erfordert, dass Namespacing-Konventionen erfüllt werden.

Außerdem wird der Initialisierer zum Laden der alten Root-Ebene verwendet lib verhindert das Neuladen während der Entwicklung.


2
2018-05-10 23:53



In gewisser Hinsicht ist hier ein einheitlicher Ansatz in Rails 5, um die eifrige und autoload Konfiguration zu zentralisieren, in der gleichen Zeit fügt es erforderlichen Autoload-Pfad hinzu, wann immer eifrig geladen wird, sonst wird es nicht in der Lage sein, richtig zu arbeiten:

# config/application.rb
...
config.paths.add Rails.root.join('lib').to_s, eager_load: true

# as an example of autoload only config
config.paths.add Rails.root.join('domainpack').to_s, autoload: true
...

1
2018-05-29 16:29



Das Verschieben des lib-Ordners in die App half dabei, ein Problem zu lösen, meine Twitter-API würde nicht in der Produktion laufen. Ich hatte "TwitterApi" nicht initialisiert und meine Twitter-API befand sich in meinem lib-Ordner. ich hatte config.autoload_paths += Dir["#{Rails.root}/app/lib"] in meiner application.rb, aber es hat nicht funktioniert, bevor Sie den Ordner verschieben.

Das hat den Trick gemacht


0
2017-11-15 23:54