20

我正在编写一个具有一些依赖关系的 Rails 引擎。我已经在 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'

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

4

2 回答 2

27

我需要在我的 engine.rb 中明确包含依赖项,以便它的资产最终进入我的资产管道。不知道为什么这是必要的,因为 Alastor 的回答对我来说听起来是正确的。值得注意的是,依赖项是我使用 bundler 创建的 gem,尽管我不明白为什么这会有所作为。

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

2012 年 11 月 23 日添加

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

添加于 2015 年 3 月 20 日

我在 2 年多前所说的“Gemfiles,另一方面,在启动期间会加载所有文件”并不完全正确。这在 Rails 中大部分是正确的,默认情况下运行Bundler.require需要 Gemfile 中列出的所有依赖项,如此处的生成器文件中所示-请注意,虽然 Rails 的默认行为从 Rails3 更改为 Rails 4 如此处讨论,但两者都使用Bundler.require. 但是,有一个强有力的理由来使用Bundler.setup,然后require "dependency1"在实际依赖的任何文件中显式地使用depedency1. 请参阅vs的讨论Bundler.requireBundler.setup

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

虽然这个问题已经有几年了,而且我什至不记得我当时写的是什么 Rails Engine,但我怀疑正确的方法会更接近这个:

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

但是请注意,这不是必需的——依赖项本身应该已经定义了这个初始化器,这样简单地要求它就足够了,就像上面的引导程序示例一样。

于 2012-09-04T15:08:25.687 回答
0

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

于 2012-09-04T10:05:17.230 回答