Ruby on Rails中的Gemfile和Gemfile.lock有什么区别


Answers:


159

Gemfile此处,您可以指定要使用的宝石,并可以指定哪些版本。

Gemfile.lock文件是Bundler记录已安装的确切版本的位置。这样,当同一库/项目加载到另一台计算机上时,运行bundle install将查看Gemfile.lock并安装完全相同的版本,而不仅仅是使用Gemfile和安装最新版本。(在不同的计算机上运行不同的版本可能会导致测试失败等。)您永远不必直接编辑锁定文件。

查看Bundler的用途和原理,特别是“将代码检入版本控制”部分。


2
这就是它应该如何工作的-但显然Gemfile.lock在某些情况下(例如rails (4.0.0)require bundler (>= 1.3.0, < 2.0))包含“开放”版本,这会引起问题。任何想法如何避免那些“开放”依赖?
Guillermo Grau 2014年

158

通常,我们在Gemfile中将依赖项编写为:

gem "nokogiri", "~> 1.4.4"
gem 'bcrypt-ruby', '~> 3.0.0'
gem 'uglifier', '>= 1.2.3'
..

在这里,您基本上会说:“ 我想要nokogiri,只要它大于1.4.4版本就可以了,等等。”现在假设我已经设置了Gemfile 8个月,并且我成功安装了此要求的应用程序。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,则每台计算机都将安装相同的gems,最重要的是,它们都具有相同的版本。这将为您提供稳定且通用的部署堆栈。

Gemfile.lock是如何创建的?

它是使用第一个自动创建的:

bundle install

命令。之后,每次您运行时bundle install,bundle都会先查找Gemfile.lock并安装在那里指定的gem。在您的项目中分发此文件以保持一致和稳定是一种习惯。

如何更新Gemfile.lock?

如果您对最新版本的应用程序满意,则可以进行更新Gemfile.lock。只要反映您对的更改即可Gemfile。这意味着将依赖项更改为中的新确切版本Gemfile。在那之后运行:

bundle install

这将为您更新Gemfile.lock最新版本的应用程序。


19
一个非常好的,清晰的描述(我赞成);但是,一个nitpick:nokogiri ~> 1.4.4不允许1.5.3安装;允许的最大值将是1.4.x哪里x>=4(对于nokogiri而言1.4.7)。该~>运营商表示只有最后一位数字中所使用的宝石可以在给定的版本“大于”。例如,foo ~> a.b.c.d表示的任何版本foo都可以,只要它仍然是abc {something},而{something} >=d。另请参阅相关问题
迈克尔

1
令我感到困惑的是,您已经通过gem "nokogiri", "~> 1.4.4"在gemfile中使用指定了特定版本。捆绑器为什么不能仅使用该版本?是因为它被设计为默认情况下有意安装最新版本的gem吗?
2014年

@Jonny,请参阅michael_n的评论。〜> 1.4.4未指定确切版本。
马修·弗拉申

2
@Jonny ~> 1.4.4等效于>= 1.4.4 and < 1.5。请参阅bundler.io/v1.5/gemfile.html。对于确切的版本,只需使用gem 'foo', '1.4.4'
Matthew Flaschen

1
好的答案,但请澄清“ update Gemfile.lock? ”:这部分是说bundle install将检查Gemfile是否存在Gemfile.lock并强制实施新的限制Gemfile.lock吗?
JMess

4

Gemfile.lock

当您运行捆绑安装时,Bundler会将您使用的所有gem的全名和版本(包括Gemfile(5)中指定的gem的依赖项)持久保存到名为Gemfile.lock的文件中。

Bundler在所有随后的捆绑安装调用中都使用此文件,以确保即使应用程序在计算机之间移动,也始终使用相同的精确代码。

由于依赖关系解析的工作方式,即使是表面上很小的变化(例如,对Gemfile(5)中gem依赖关系的点发布的更新),也可能导致需要完全不同的gem来满足所有依赖关系。

因此,您应该将Gemfile.lock检查到版本控制中。如果不这样做,那么每一个签出您的存储库的机器(包括您的生产服务器)都将再次解析所有依赖关系,如果在Gemfile(5)中有任何gems或任何其他gem,则将导致使用不同版本的第三方代码。他们的依赖关系已更新。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.