Rails 3.1 引擎:my_engine.gemspec、add_dependency、add_development_dependency 和 Gemfile 的区别
Posted
技术标签:
【中文标题】Rails 3.1 引擎:my_engine.gemspec、add_dependency、add_development_dependency 和 Gemfile 的区别【英文标题】:Rails 3.1 Engines: Difference of my_engine.gemspec, add_dependency, add_development_dependency, and Gemfile 【发布时间】:2012-09-12 15:26:42 【问题描述】:只是出于好奇...在我之前的帖子Rails3.1 engine: can't get SLIM or HAML to work in test/dummy app 中,我问到哪里可以告诉Ruby 在我的test/dummy
应用程序中使用一些gem。
(显然?)答案是将其放入我的引擎的 Gemfile 中。这行得通,但它让我有点不舒服,因为在 Yehuda Katz 的帖子Clarifying the Roles of the .gemspec and Gemfile 他提到...
...在开发 gem 时,Gemfile “gem 的 Gemfile 应该包含 Rubygems 源代码和单个 gemspec 行”。
另一方面,在我的 Engine 的 Gemfile(使用 Rails 的rails plugin new my_engine
生成)中有:
# jquery-rails is used by the dummy application
gem "jquery-rails"
所以这似乎是正确的。 更新:不,它没有!看看我下面的答案...
不过,somewhere else on *** 我看到解决方案据说只需要 config/application.rb
中所需的 gem,而 https://***.com/questions/5159607/rails-engine-gems-dependencies-how- to-load-them-into-the-application 它被告知最好放入lib/<your_engine>/engine.rb file
。
这是我的想法:为什么test/dummy
应用程序不简单地自动要求.gemspec
文件中指定的所有宝石?我们甚至通过显式使用add_dependency
和add_development_dependency
告诉gem,哪些gem 用于生产,哪些用于开发模式,所以我看不出test/dummy
不这样做的任何原因。
所以这是最后一个问题:我必须在哪里告诉 Ruby 在我的test/dummy
应用程序中使用 gem?我不想强迫 Ruby 在主机应用程序中也使用宝石。
【问题讨论】:
+1 提问;期待你得到的答案:-) 用我目前的发现为问题添加了一些更有趣的信息(参见更新)。 感谢您的更新。会为它 +1,但不能做两次 ;-) gemfile 组的事情看起来很奇怪。 【参考方案1】:TL;DR:
在开发引擎时不要使用任何Gemfile
。将所有内容放在引擎的gemspec
中,让引擎本身需要它所需的一切。
为什么测试/虚拟应用不简单地自动要求 .gemspec 文件中指定的所有 Gem?
我猜应用程序不会出于性能原因自动要求其引擎的依赖项。
因此,如果虚拟应用程序应该是使用引擎对真实应用程序的真实模拟,那么它也不应该这样做。
另外,假设虚拟应用程序是自动需要所有依赖项,包括开发依赖项。在这种情况下,即使您的开发依赖项之一实际上是运行时依赖项,您的测试也可能会成功。那真的很烦人。
据说只需要 config/application.rb 中所需的 gem
这也可能掩盖引擎的运行时依赖关系,所以最好不要这样做。
所以这是最后一个问题:我必须在哪里告诉 Ruby 在我的测试/虚拟应用程序中使用 gem?我不想强迫 ruby 在主机应用程序中也使用 gem。
如果该 gem 只是用于测试,请在您的测试/规范助手中使用它。
否则,如果您的引擎需要该 gem 来运行,您真的应该强制使用它。
James:这会让我相信引擎的依赖项放在 gemspec 中,而虚拟应用程序的依赖项放在 Gemfile 中
虚拟应用的捆绑程序存根实际上引用了虚拟应用自己的、缺少的 Gemfile。所以我想它是故意遗漏的。这很有意义。
这样想:您对虚拟应用所做的任何更改都会导致测试无法在中性背景下执行,因此不具有代表性。
如果您真的希望能够重用您的引擎,并将其放入任何空白的新 Rails 应用程序中,您的虚拟应用程序应该就是:一个空白的新 Rails 应用程序。
【讨论】:
【参考方案2】:我认为正确的方法如下:
引擎是一个普通的宝石。开发 gem 时,将其依赖项放在 gemspec
文件中。如果您使用 bundle,作为开发人员,您可以创建一个 .lock
文件,其中包含您没有问题的特定版本。但是在 gemspec
中声明的依赖项不足以使用它们,您必须在 gem 代码中 require
它们。需要时,如果 gem 与 bundle 一起使用,则使用 .lock
版本。
在引擎中,与任何其他 gem 一样,它是相同的。您在 gemspec
文件中定义您的依赖项并运行 bundle install
但仅使用它们是不够的。例如,您必须在 lib/my_engine.rb
中要求它们。
例如:
# File: my_engine.rspec
# ...
s.add_dependency `slim_rails`, ' ~>1.0'
# ...
# File: lib/my_engine.rb
require "my_engine/engine"
require "slim-rails"
module MyEngine
end
我不确定如果在Gemfile
中设置它们,为什么使用它们没有更多麻烦,但正如rails documentation 所说:
引擎内的 Gem 依赖项应在 .gemspec 文件位于引擎的根目录。原因是发动机 可以作为 gem 安装。如果要在内部指定依赖项 Gemfile,这些不会被传统的 gem 识别 安装,所以它们不会被安装,导致引擎 故障。
【讨论】:
感谢您的回答(很抱歉我忘记了这篇文章)。不过,我还是有点困惑。【参考方案3】:这是我目前发现的。
在引擎(使用rails plugin new my_engine
创建)中,您必须在 my_engine.gemspec 文件中仅指定所需的 gem,然后使用 @987654323 从 test/dummy/Gemfile 中引用它们@。
这是生成的 test/dummy/Gemfile 内容:
source "http://rubygems.org"
# Declare your gem's dependencies in simple_view_helpers.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gemspec
# jquery-rails is used by the dummy application
gem "jquery-rails"
# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.
# To use debugger
# gem 'debugger'
gem "jquery-rails"
行在这里做什么我真的不知道,似乎与 cmets 中提出的完全矛盾。另一方面,当我尝试在我的测试/虚拟应用程序中使用 SLIM gem(而不是 ERB)时,似乎我 确实 必须在 Gemfile 中指定它,否则它不会工作。还是有点乱,这玩意……
【讨论】:
奇怪,在较新版本的 Rails (3.2.11) 中,用于引擎的Gemfile
位于根目录中,而测试虚拟应用程序没有。这会让我相信引擎的依赖项放在gemspec
中,而虚拟应用程序的依赖项放在Gemfile
中。以上是关于Rails 3.1 引擎:my_engine.gemspec、add_dependency、add_development_dependency 和 Gemfile 的区别的主要内容,如果未能解决你的问题,请参考以下文章