rubygems ruby-on-rails-3.1 asset-pipeline ruby-on-rails-plugins

rubygems - Dependencia incluida en gemspec no agregada a la tubería de activos en el motor de rieles



ruby-on-rails-3.1 asset-pipeline (2)

¿Diseñó su motor de acuerdo con el http://edgeguides.rubyonrails.org/engines.html ? Si su clase de motor se hereda de Rails :: Engine, realmente debería encontrar todos los activos por sí mismo.

Estoy escribiendo un motor de rieles que tiene algunas dependencias. He especificado las dependencias en el gemspec y el motor las encuentra cuando ejecuto bundle install (es decir, Gemfile.lock parece correcto). Cuando quiero usar el complemento en un archivo de Ruby, puedo hacerlo pero necesito explícitamente require dependency-name en la parte superior del archivo.

Sin embargo, cuando quiero usar el flujo de activos de la dependencia, los piñones no pueden encontrarlo.

La aplicación que estoy usando (por ahora) es la aplicación ficticia que viene en la carpeta de prueba de un plugin de rieles. Sprockets puede encontrar los activos si los especifico en el Gemfile del motor (que en realidad es el Gemfile de la aplicación ficticia), pero no si los especifico en la gemspec. No quiero confiar en Gemfile porque eso significa que cualquier aplicación que use mi complemento deberá agregar manualmente todas mis dependencias a su Gemfile. Por la misma razón, no quiero una solución que implique actualizar el archivo de configuración de la aplicación.

Esto funciona (en un archivo ruby) cuando se incluye la dependencia de gemspec:

require ''dependency-name''

pero esto (en un archivo JS) no funciona cuando se incluye la dependencia de gemspec:

//= require ''dependency-name''

No se require ningún require cuando se incluye la dependencia de Gemfile. Creo que está bastante claro, pero avísame si necesitas más detalles.


Necesitaba incluir la dependencia explícitamente en mi engine.rb para que sus activos terminen en mi cartera de activos. No estoy seguro de por qué esto es necesario, ya que la respuesta de Alastor me pareció correcta. Vale la pena señalar que las dependencias son gemas que creé usando el agrupador, aunque no veo por qué eso debería hacer una diferencia.

module MyRailsPluginFull class Engine < ::Rails::Engine require ''dependency1'' require ''dependency2'' end end

Añadido el 23/11/12

Habiendo pasado más tiempo trabajando con Engines, creo que ahora entiendo esto más completamente. Las Gemspecs son solo de una lista de dependencias que se requieren, pero Gemspec no le indica a la aplicación, en el inicio, que cargue los archivos de esas dependencias. Gemfiles, por otro lado, carga todos los archivos durante el inicio.

Añadido el 20/3/2015

Mi afirmación de hace más de 2 años de que "Gemfiles, por otro lado, carga todos los archivos durante el inicio" no es del todo cierta. Es cierto en su mayoría en Rails, que de forma predeterminada ejecuta Bundler.require Requieren requerir todas las dependencias enumeradas en Gemfile, como se muestra en el archivo del generador here . Tenga en cuenta que si bien el comportamiento predeterminado de Rails cambió de Rails3 a Rails 4 como se explica here , ambos utilizar Bundler.require . Sin embargo, hay un caso sólido para usar Bundler.setup y luego un require "dependency1" explícito require "dependency1" en cualquier archivo que realmente dependa de depedency1 . Vea esta discusión de Bundler.require versus Bundler.setup .

Además, como @nruth señala en los comentarios, esto puede llevar a la carga de clases innecesarias. Sin embargo, si la dependencia está bien diseñada, la mayoría de las clases se cargarán automáticamente, lo que creará una sobrecarga mínima para requerir la dependencia completa. Alternativamente, si define su motor en un archivo que puede ser requerido en forma aislada, puede simplemente incluir el archivo del motor, que debe agregar los archivos necesarios a su ruta de activos, permitiéndole requerir sus activos en sus manifiestos de CSS y JS. Vea este ejemplo de bootstrap-sass , donde la gema agrega todos sus activos a config.assets.paths y agrega algunos de ellos a config.assets.precompile .

Si bien esta pregunta tiene algunos años y ni siquiera recuerdo qué Rails Engine estaba escribiendo en ese momento, sospecho que la forma correcta de hacerlo habría sido más cercana a esto:

module MyRailsPluginFull class Engine < ::Rails::Engine initializer ''bootstrap-sass.assets.precompile'' do |app| require ''dependency1'' # add dependency1''s assets to the list of paths app.config.assets.paths << ... end end end

Pero tenga en cuenta que esto no debería ser necesario: la dependencia en sí misma debería haber definido este inicializador, de modo que simplemente requerirlo sería suficiente, como lo hace el ejemplo anterior.