Pertanyaan Rails 5: Memuat file lib dalam produksi


Saya telah meningkatkan salah satu aplikasi saya dari Rails 4.2.6 ke Rails 5.0.0. Itu Panduan Upgrade mengatakan, bahwa fitur Autoload sekarang dinonaktifkan dalam produksi secara default.

Sekarang saya selalu mendapatkan kesalahan pada server produksi saya karena saya memuat semua file lib dengan autoload di application.rb mengajukan.

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

Untuk saat ini, saya telah mengatur config.enable_dependency_loading untuk true tapi saya ingin tahu apakah ada solusi yang lebih baik untuk ini. Harus ada alasan bahwa Autoloading dinonaktifkan dalam produksi secara default.


75
2017-07-05 08:30


asal


Jawaban:


Daftar perubahan saya setelah pindah ke Rails 5:

  1. Tempat lib dir kedalam app karena semua kode di dalam aplikasi dimuat otomatis di dev dan bersemangat dimuat di prod dan yang paling penting adalah autoreloaded dalam pengembangan sehingga Anda tidak perlu me-restart server setiap kali Anda melakukan perubahan.
  2. Hapus semua require pernyataan yang menunjuk ke kelas Anda sendiri di dalam lib karena mereka semua masih otomatis dimuat jika penamaan file / dir mereka benar, dan jika Anda pergi require pernyataan itu dapat mematahkan autoreloading. Info lebih lanjut sini
  3. Set config.eager_load = true di semua lingkungan untuk melihat masalah pemuatan kode dengan penuh semangat di dev.
  4. Menggunakan Rails.application.eager_load! sebelum bermain dengan utas untuk menghindari kesalahan "ketergantungan melingkar".
  5. Jika Anda memiliki ekstensi ruby ​​/ rel kemudian tinggalkan kode itu di dalam yang lama lib direktori dan memuatnya secara manual dari penginisialisasi. Ini akan memastikan bahwa ekstensi dimuat sebelum logika Anda selanjutnya yang dapat bergantung padanya:

    # 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



Saya baru saja digunakan config.eager_load_paths dari pada config.autoload_paths suka menyebutkan akostadinov di komentar github: https://github.com/rails/rails/issues/13142#issuecomment-275492070

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

Ia bekerja pada lingkungan pengembangan dan produksi.

Terima kasih Johan untuk saran untuk menggantikan #{Rails.root}/lib dengan Rails.root.join('lib')!


32
2017-07-08 11:32



Autoloading dinonaktifkan di lingkungan produksi karena keamanan benang. Terima kasih kepada @ Зелёный untuk tautannya.

Saya memecahkan masalah ini dengan menyimpan file lib dalam lib folder di saya app direktori seperti yang direkomendasikan pada Github. Setiap folder dalam app folder dimuat oleh Rails secara otomatis.


24
2017-08-18 17:34



Harus ada alasan bahwa Autoloading dinonaktifkan dalam produksi oleh   default.

Berikut ini adalah diskusi panjang tentang masalah ini. https://github.com/rails/rails/issues/13142


17
2017-07-05 08:43



Ini memungkinkan untuk memiliki aut auteleload, dan bekerja di lingkungan produksi juga.

P.S. Saya telah mengubah jawaban saya, sekarang ini menambah baik jalur auto-muat, terlepas dari lingkungan, untuk memungkinkan bekerja di lingkungan kustom juga (seperti tahap)

# 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



Bagi siapa pun yang berjuang dengan ini seperti saya, itu tidak cukup hanya menempatkan direktori di bawah app/. Ya, Anda akan mendapatkan autoloading tetapi tidak diperlukan reload, yang membutuhkan konvensi namespacing harus dipenuhi.

Juga, menggunakan penginisialisasi untuk memuat tingkat-root lama lib akan mencegah fitur reload selama pengembangan.


2
2018-05-10 23:53



Dalam beberapa hal, di sini adalah pendekatan terpadu dalam Rails 5 untuk memusatkan konfigurasi bersemangat dan autoload, dalam waktu yang sama ia menambahkan jalur autoload yang diperlukan kapan pun beban yang diinginkan dikonfigurasi, jika tidak, ia tidak akan dapat bekerja dengan benar:

# 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