我是一个Ruby on Rails的初学者,目前正在使用Rails 3.0.9。
Gemfile
和Gemfile.lock
在Rails中有什么区别?
我是一个Ruby on Rails的初学者,目前正在使用Rails 3.0.9。
Gemfile
和Gemfile.lock
在Rails中有什么区别?
Gemfile
文件用于指定你要使用哪些gem,并允许你指定它们的版本。
Gemfile.lock
文件是Bundler记录安装的确切版本的地方。这样,当在另一台机器上加载相同的库/项目时,运行bundle install
将查看Gemfile.lock
并安装完全相同的版本,而不仅仅是使用Gemfile
和安装最新版本。(在不同的机器上运行不同的版本可能会导致测试失败等问题。)您不应直接编辑lock文件。
请查看 Bundler的目的和基本原理,特别是“将您的代码检入版本控制”部分。
通常我们将依赖项写在 Gemfile 中:
gem "nokogiri", "~> 1.4.4"
gem 'bcrypt-ruby', '~> 3.0.0'
gem 'uglifier', '>= 1.2.3'
..
这里你基本上是在说:“只要nokogiri的版本大于1.4.4,我就想要它”,等等。现在假设我8个月前设置了我的Gemfile
并成功地使用了这个要求来设置我的应用程序。8个月前nokogiri的版本是1.4.4。我的rails应用程序正常运行,没有任何问题。
现在假设我尝试使用相同的Gemfile
构建。但是如果我们查看nokogiri的版本,我们会发现当前稳定版本已经更新到了1.4.9。这意味着如果我们试图构建,bundler将安装nokogiri的1.4.9版本(假设我们没有Gemfile.lock
)。
正如您所看到的,如果您没有任何Gemfile.lock
并运行:
bundle install
当前使用的宝石随时可能会有所不同。您的应用程序使用版本 1.4.4,并且在8个月前没有任何问题,但是如果您现在尝试构建它,您将得到版本 1.4.9 。也许它在nokogiri
的最新版本中出了问题,您使用的很棒的功能在 1.4.4 中已不再可用等等。
为了防止这种问题,使用Gemfile.lock
。在Gemfile.lock
中仅编写确切的版本,因此只会安装这些版本。这意味着如果您使用Gemfile.lock
分发应用程序,则每台机器都会安装相同的宝石,而最重要的是它们都获得相同的版本。这将为您提供稳定和共同的部署栈。
它是通过第一个命令自动创建的:
bundle install
每次运行bundle install
命令时,都会首先查找Gemfile.lock
并安装其中指定的gems。将此文件分发到您的项目中可以提供一致性和稳定性,这是一种习惯。
如果您满意应用程序的最新版本,则可以更新Gemfile.lock
。只需在Gemfile
中反映出您的更改即可,也就是将依赖项更改为Gemfile
中的新精确版本。之后运行:
bundle install
这将使用您的最新应用版本更新Gemfile.lock
。
nokogiri ~> 1.4.4
不允许安装 1.5.3
,最大允许的版本是 1.4.x
,其中 x>=4
(对于 nokogiri 来说,这将是 1.4.7
)。~>
运算符表示只能使用 gem 中的 最后一位数字 大于给定版本。例如,foo ~> a.b.c.d
表示任何版本的 foo
都可以,只要它仍然是 a.b.c.{something},其中{something} >=
d。另请参见 相关问题。 - michaelgem "nokogiri", "~> 1.4.4"
来指定特定版本(或版本范围)。那么为什么Bundler不能直接使用该版本呢?难道这是因为它默认会有意地安装最新版本的gem吗? - Jonny~> 1.4.4
相当于 >= 1.4.4 and < 1.5
。请参阅 http://bundler.io/v1.5/gemfile.html 。要使用精确版本,请使用 gem 'foo','1.4.4'
。 - Matthew FlaschenGemfile.lock
,bundle install
也会检查Gemfile
并对Gemfile.lock
强制执行新的限制? - JMessGemfile.lock
当你运行 bundle install 时,Bundler 将记录所使用的所有 gem 的完整名称和版本(包括 Gemfile(5) 中指定的 gem 的依赖关系)到一个名为 Gemfile.lock 的文件中。
Bundler 在每次调用 bundle install 时都会使用此文件,以确保您始终使用完全相同的代码,即使您的应用程序在不同的机器上移动也是如此。
由于依赖关系解析的方式,即使看似很小的更改(例如,Gemfile(5) 中某个 gem 的依赖项的点发行版更新)也可能导致需要使用完全不同的 gem 来满足所有依赖项。
因此,您应该将 Gemfile.lock 检入版本控制。如果没有检入版本控制,则检出您的存储库的每台机器(包括生产服务器)都将重新解析所有依赖项,这将导致使用不同版本的第三方代码,如果 Gemfile(5) 中的任何 gem 或其依赖项已更新。
Gemfile.lock
包括“开放”的版本(例如,rails(4.0.0)
需要bundler(>= 1.3.0,<2.0)
),这会导致问题。有任何想法来避免这些“开放”依赖关系吗? - Guillermo Grau