Pregunta Rails 5: carga de archivos lib en producción


Actualicé una de mis aplicaciones de Rails 4.2.6 a Rails 5.0.0. los Guía de actualización dice, que la función Autoload ahora está desactivada en producción por defecto.

Ahora siempre obtengo un error en mi servidor de producción ya que cargo todos los archivos lib con autocarga en el application.rb archivo.

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

Por ahora, he establecido el config.enable_dependency_loading a true pero me pregunto si hay una mejor solución para esto. Debe haber un motivo por el que la carga automática esté desactivada en la producción de manera predeterminada.


75
2017-07-05 08:30


origen


Respuestas:


Mi lista de cambios después de pasar a Rails 5:

  1. Lugar lib dir en app porque todo el código dentro de la aplicación es autocargado en desarrollo y ansioso de cargar en prod y lo más importante es autorecargado en desarrollo para que no tenga que reiniciar el servidor cada vez que realice cambios.
  2. Eliminar cualquier require declaraciones que apuntan a sus propias clases dentro lib porque todos están autocargados de todos modos si su nombre de archivo / dir es correcto, y si te vas require declaraciones que pueden interrumpir la autorrecarga. Más información aquí
  3. Conjunto config.eager_load = true en todos los entornos para ver problemas de carga de código ansiosamente en dev.
  4. Utilizar Rails.application.eager_load! antes de jugar con hilos para evitar errores de "dependencia circular".
  5. Si tiene alguna extensión de ruby ​​/ rails, deje ese código dentro de lib directorio y cargarlos manualmente desde el inicializador. Esto asegurará que las extensiones se carguen antes de su lógica adicional que pueda depender de ella:

    # 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



Acabo de usar config.eager_load_paths en lugar de config.autoload_paths como mencionar akostadinov en github comment: https://github.com/rails/rails/issues/13142#issuecomment-275492070

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

Funciona en el entorno de desarrollo y producción.

Gracias Johan para sugerencia de reemplazar #{Rails.root}/lib con Rails.root.join('lib')!


32
2017-07-08 11:32



La carga automática está desactivada en el entorno de producción debido a la seguridad del hilo. Gracias a @ Зелёный por el enlace.

Resolví este problema almacenando los archivos lib en un lib carpeta en mi app directorio como se recomienda en Github. Cada carpeta en el app la carpeta se carga automáticamente por Rails.


24
2017-08-18 17:34



Debe haber una razón por la que la función Auto carga está deshabilitada en producción por   defecto.

Aquí hay una larga discusión sobre este tema. https://github.com/rails/rails/issues/13142


17
2017-07-05 08:43



Esto permite tener autorrecarga de lib y también funciona en el entorno de producción.

PD He cambiado mi respuesta, ahora se agrega a ambas rutas de carga automática, independientemente del entorno, para permitir el trabajo en entornos personalizados también (como etapa)

# 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



Para alguien que luchó con esto como yo, no es suficiente colocar un directorio debajo app/. Sí, obtendrás carga automática pero no es necesario recargar, lo que requiere que se cumplan las convenciones de espaciado de nombres.

Además, usando el inicializador para cargar el viejo nivel de raíz lib evitará la función de recarga durante el desarrollo.


2
2018-05-10 23:53



En cierto sentido, aquí hay un enfoque unificado en Rails 5 para centralizar la configuración ansiosa y de carga automática, al mismo tiempo que agrega la ruta de autocarga requerida siempre que se configure la carga ansiosa, de lo contrario no podrá funcionar correctamente:

# 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