Рельсы 5: загрузка lib файлов в производство


я обновил одно из моих приложений с Rails 4.2.6 до Rails 5.0.0. Элемент Руководство По Обновлению говорит, что функция автозагрузки отключена в производстве по умолчанию.

теперь я всегда получаю сообщение об ошибке на моем рабочем сервере, так как я загружаю все lib файлы с автозапуском в .

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

на данный момент, я установил config.enable_dependency_loading до true но мне интересно, есть ли лучшее решение для этого. Должна быть причина, по которой автоматическая загрузка отключена производство по умолчанию.

8 81

8 ответов:

мой список изменений после перехода на рельсы 5:

  1. место lib реж в app потому что весь код внутри приложения autoloaded в dev и жаждущих загружен в прод и самое главное-это autoreloaded в разработке, так что вам не придется перезапускать сервер каждый раз, когда вы вносите изменения.
  2. удалить все require операторы, указывающие на ваши собственные классы внутри lib потому что все они автоматически загружаются в любом случае, если их имена файлов/dir верны, и если вы оставите require заявления он может нарушить автозапуск. Подробнее здесь
  3. Set config.eager_load = true во всех средах, чтобы увидеть проблемы загрузки кода с нетерпением в dev.
  4. использовать Rails.application.eager_load! перед игрой с потоками, чтобы избежать ошибок "круговой зависимости".
  5. если у вас есть какие-либо расширения ruby/rails, то оставьте этот код внутри старого

Я только что использовал config.eager_load_paths вместо config.autoload_paths как упоминание акостадинов на 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')

оно работает на окружающей среде развития и продукции.

спасибо Йохан предложение заменить #{Rails.root}/lib С Rails.root.join('lib')!

автоматическая загрузка отключена в производственной среде из-за безопасности потока. Спасибо @Зелёный за ссылку.

я решил эту проблему, сохранив файлы lib в в своем

должна быть причина, по которой автоматическая загрузка отключена в производстве по умолчанию.

вот долгая дискуссия по этому вопросу. https://github.com/rails/rails/issues/13142

Это позволяет иметь lib autoreload, и работает в производственной среде тоже.

P.S. Я изменил свой ответ, теперь он добавляет к обоим путям автоматической загрузки, независимо от среды, чтобы разрешить работу в пользовательских средах (например, stage)

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

для тех, кто боролся с этим, как я, недостаточно просто разместить каталог под app/. Да, вы получите автозапуск, но не обязательно перезагрузка, которая требует выполнения соглашений о пространстве имен.

кроме того, используя инициализатор для загрузки старого корневого уровня lib предотвратит перезагрузку функции во время разработки.

в некотором смысле, вот унифицированный подход в Rails 5 для централизации конфигурации eager и autoload, в то же время он добавляет требуемый путь autoload всякий раз, когда настроена нагрузка eager, иначе она не сможет работать правильно:

# 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
...

перемещение папки lib в приложение помогло решить проблему, мой api Twitter не будет работать в производстве. У меня был "неинициализированный постоянный TwitterApi", и мой API Twitter был в моей папке lib. У меня было config.autoload_paths += Dir["#{Rails.root}/app/lib"] в моем приложении.rb, но он не работал до перемещения папки.

это сделал трюк