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_dependencyadd_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 的区别的主要内容,如果未能解决你的问题,请参考以下文章

Rails 3.1 资产管道和缓存

导轨 3.1。如何防止 Rails 使用 CoffeeScript?

Rails 3.1 实时预览

rails 3.1邮件程序中的asset_url

Rails 3.1 - 忽略 CSRF?

Rails 3.1 指南针和链轮。使困惑