Answers:
在Gemfile
此处,您可以指定要使用的宝石,并可以指定哪些版本。
该Gemfile.lock
文件是Bundler记录已安装的确切版本的位置。这样,当同一库/项目加载到另一台计算机上时,运行bundle install
将查看Gemfile.lock
并安装完全相同的版本,而不仅仅是使用Gemfile
和安装最新版本。(在不同的计算机上运行不同的版本可能会导致测试失败等。)您永远不必直接编辑锁定文件。
查看Bundler的用途和原理,特别是“将代码检入版本控制”部分。
通常,我们在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,最重要的是,它们都具有相同的版本。这将为您提供稳定且通用的部署堆栈。
它是使用第一个自动创建的:
bundle install
命令。之后,每次您运行时bundle install
,bundle都会先查找Gemfile.lock
并安装在那里指定的gem。在您的项目中分发此文件以保持一致和稳定是一种习惯。
如果您对最新版本的应用程序满意,则可以进行更新Gemfile.lock
。只要反映您对的更改即可Gemfile
。这意味着将依赖项更改为中的新确切版本Gemfile
。在那之后运行:
bundle install
这将为您更新Gemfile.lock
最新版本的应用程序。
gem "nokogiri", "~> 1.4.4"
在gemfile中使用指定了特定版本。捆绑器为什么不能仅使用该版本?是因为它被设计为默认情况下有意安装最新版本的gem吗?
~> 1.4.4
等效于>= 1.4.4 and < 1.5
。请参阅bundler.io/v1.5/gemfile.html。对于确切的版本,只需使用gem 'foo', '1.4.4'
。
bundle install
将检查Gemfile
是否存在Gemfile.lock
并强制实施新的限制Gemfile.lock
吗?
Gemfile.lock
当您运行捆绑安装时,Bundler会将您使用的所有gem的全名和版本(包括Gemfile(5)中指定的gem的依赖项)持久保存到名为Gemfile.lock的文件中。
Bundler在所有随后的捆绑安装调用中都使用此文件,以确保即使应用程序在计算机之间移动,也始终使用相同的精确代码。
由于依赖关系解析的工作方式,即使是表面上很小的变化(例如,对Gemfile(5)中gem依赖关系的点发布的更新),也可能导致需要完全不同的gem来满足所有依赖关系。
因此,您应该将Gemfile.lock检查到版本控制中。如果不这样做,那么每一个签出您的存储库的机器(包括您的生产服务器)都将再次解析所有依赖关系,如果在Gemfile(5)中有任何gems或任何其他gem,则将导致使用不同版本的第三方代码。他们的依赖关系已更新。
Gemfile.lock
在某些情况下(例如rails (4.0.0)
requirebundler (>= 1.3.0, < 2.0)
)包含“开放”版本,这会引起问题。任何想法如何避免那些“开放”依赖?