bundle.setup和bundle.require之间的区别是什么

在gemfile手册页中 ,我了解到有两种方法可以导入您在Gemfile指定的Gemfilebundle.setup将“设置为Ruby的加载路径添加gem”,而bundle.require将需要所有的gem。

这两种方法有什么区别? 我应该在哪种情况下使用其中一种?

Bundler.setup修改了LOAD_PATH,因此你可以做一些像require 'some_gem'东西,它们会起作用。 它允许您“手动”需要gem。 在Bundler之前,使用Rubygems,你可以在require 'rubygems'获得很多相同的效果。

Bundler.require(:default)实际上需要Gemfile中的所有gem(假设您没有使用组;否则,如果您提供参数,则需要指定组中的那些)。 它是一堆require 'some_gem'语句的简写。

请参见http://gembundler.com/rationale.html 。 请注意,他们说在执行Bundler.require之前require 'bundler/setup' ,但实际上这通常不是必需的。 我几乎从不使用Bundler.setup (或者require 'bundler/setup ),因为我需要通过Bundler.require所有gem。

您必须使用Bundle.setup并且可以使用Bundle.require

捆绑器的主要目的是确保Gemfile中定义的Gems对应用程序是可见的,即所提到的所有gem都是完全提到的版本,但不是一个。 为此,调整负载路径。 这是由Bundle.setup完成的。

要实际使用gem,必须将它们加载到应用程序中。 这可以使用许多require语句手动完成,也可以使用Bundle.require自动完成Gemfile(或仅某些组)中列出的所有gem。 然而,这仅在适应如上所述的负载路径之后才可能。

Bundle.setup对于最近的bundler版本来说不是必需的。 事实上,当你运行Bundler.require ,它总是试图为你设置​​正确的$LOAD_PATH

唯一的需要是:

require 'bundler' Bundler.require

我将在Rails的上下文中回答这个问题。 我正在审查Rails初始化过程,并遇到了“bundler / setup”和Bundler.require。 记住Bundler的目标:安装所需的gem,并确保这些是Rails应用程序中唯一需要的gem。 这就是它与Rails一起工作的方式:

在初始化中,Rails环境首先加载bin / rails的内容。 它需要两个重要文件:

 require_relative '../config/boot' require 'rails/commands' 

配置/启动是这里最关键的一个。 它首先将Gemfile存储在环境变量中,然后运行bundler / setup。

 ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) 

我注意到的一件事显然是你可以通过设置环境变量BUNDLE_GEMFILE来选择使用不同的Gemfile。 但更重要的是,由于’bundler / setup’,$ LOAD_PATH已更改。 通常RubyGems有一个默认的$ LOAD_PATH,它会在你使用“require”时搜索文件。 好吧,bundler / setup从$ LOAD_PATH中删除了所有gems路径(这反转了RubyGems所做的任何加载路径工作)。 然后,它将Gemfile.lock中的gems的加载路径添加回$ LOAD_PATH。 现在,您可以要求文件的唯一gem是Gemfile中的gem。

有趣的是,即使RubyGems有一个默认的$ LOAD_PATH,在使用“require”时会搜索,你仍然需要使用“require”。 gem不是必需的。 但是当你使用Bundler和Rails时,你不需要在Gemfile中需要任何Gems。 这是如何完成的? 这是由Bundler.require处理的! 回到bin / rails文件中,有这一行:

 APP_PATH = File.expand_path('../../config/application', __FILE__) 

APP_PATH就是在这里设置的。 没装。 但是当你运行类似rails服务器的东西时,将使用APP_PATH,因此将加载config / application.rb文件,因此如下:

 require 'rails/all' Bundler.require(*Rails.groups) 

在Rails启动后运行config / application.rb,在上面的内容中,Bundler.require需要传递给它的所有组中的所有gem。 (“groups”是指您在Gemfile中指定的组。)当您在开发模式下运行Rails时,Rails.groups将是[:default,:development],[:default,:production]在生产模式下,等等。 :默认组包括未在任何组下列出的所有gem。 因此,Bundler将在您的Gemfile中查找属于每个组的gem,并在它找到的每个gem上调用require。