首页 文章

gemspec中包含的依赖关系未添加到rails引擎中的资产管道中

提问于
浏览
20

我'm writing a rails engine that has some dependencies. I' ve指定了gemspec中的依赖项,当我运行 bundle install (即Gemfile.lock看起来正确)时引擎正在找到它们 . 当我想在Ruby文件中使用插件时,我可以这样做,但需要在文件顶部显式 require dependency-name .

但是,当我想使用依赖项的资产管道时,sprockets无法找到它 .

我正在使用的应用程序(现在)是一个虚拟应用程序,它位于rails插件的测试文件夹中 . 如果我在引擎的Gemfile(实际上是虚拟应用程序的Gemfile)中指定它们,Sprockets可以找到资产,但如果我在gemspec中指定它们则不会 . 我不想依赖Gemfile,因为这意味着任何使用我的插件的应用都需要手动将我的所有依赖项添加到他们的Gemfile中 . 出于同样的原因,我不想要一个涉及更新应用程序配置文件的解决方案 .

当从gemspec中包含依赖项时,这适用于(在ruby文件中):

require 'dependency-name'

但是当从gemspec中包含依赖项时,这(在JS文件中)不起作用:

//= require 'dependency-name'

当Gemfile中包含依赖项时,不需要 require . 我认为这很清楚,但如果您需要更多细节,请告诉我 .

2 回答

  • 27

    我需要在我的engine.rb中明确包含依赖项,以使其资产最终出现在我的资产管道中 . 不知道为什么这是必要的,因为Alastor的答案听起来对我来说是正确的 . 值得注意的是,依赖关系是我使用bundler创建的宝石,但我不明白为什么这应该有所作为 .

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

    Added 11/23/12

    花了一些时间与Engines合作,我想我现在更全面地理解了这一点 . Gemspec只是所需的依赖项列表,但gemspec并不指示应用程序在启动时从这些依赖项加载文件 . 另一方面,Gemfiles会在启动期间加载所有文件 .

    Added 3/20/2015

    我在2年多前发表的声明认为"Gemfiles, on the other hand, do load all the files during startup"并不完全正确 . 在Rails中大多数情况下都是如此,它默认运行 Bundler.require 以要求Gemfile中列出的所有依赖项,如生成器文件_2696654中所示 - 请注意,虽然Rails的默认行为从Rails3更改为Rails 4,如讨论here,但两者都使用 Bundler.require . 但是,有一个强有力的案例可以使用 Bundler.setup ,然后在实际依赖于 depedency1 的文件中使用显式 require "dependency1" . 请参阅 Bundler.requireBundler.requireBundler.setup .

    另外,正如@nruth在评论中指出的那样,这可能导致加载不必要的类 . 但是,如果依赖项设计得很好,那么它的类将主要被自动加载,从而为需要整个依赖项创建最小的开销 . 或者,如果它在一个可以单独使用的文件中定义其引擎,您可以只包含引擎文件,该文件应该将必要的文件添加到资产路径中,从而允许您在CSS和JS清单中要求其资产 . 请参阅this bootstrap-sass example,其中gem将其所有资产添加到 config.assets.paths ,并将其中一些添加到 config.assets.precompile .

    虽然这个问题已经存在了几年,我甚至不记得当时正在编写的Rails引擎,但我怀疑正确的方法可能更接近于此:

    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
    

    但请注意,这不应该是必要的 - 依赖本身应该已经定义了这个初始化程序,因此只需要它就足够了,就像上面的bootstrap示例那样 .

  • 0

    你根据http://edgeguides.rubyonrails.org/engines.html设计了引擎?如果您的引擎类继承自Rails :: Engine,它实际上应该自己找到所有资产 .

相关问题