我需要在我的 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.require
Bundler.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
但是请注意,这不是必需的——依赖项本身应该已经定义了这个初始化器,这样简单地要求它就足够了,就像上面的引导程序示例一样。