为什么Bundler.require不需要依赖?

时间:2016-01-19 07:19:05

标签: ruby-on-rails ruby rubygems bundler

我正在开发一颗宝石。以下是.gemspec的外观:

gem.add_dependency 'activerecord', '~> 4.2'
...

gem.add_development_dependency 'rails', '4.2.5'
...

这是我的Gemfile

source 'https://rubygems.org'

gemspec

我正在设置我的主文件lib/my_gem.rb,如下所示:

module MyGem
  module Lib
  end
end

ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
Bundler.require

但是,如果我从gem的文件夹中启动bundle console,则不需要依赖项:

$ bundle console
Resolving dependencies...
irb(main):001:0> Rails
NameError: uninitialized constant Rails
...
irb(main):002:0> ActiveRecord
NameError: uninitialized constant ActiveRecord
...

我做错了什么?

1 个答案:

答案 0 :(得分:1)

我认为gemspec中的Gemfile命令所包含的依赖关系并非Bundler.require自动要求。只有Gemfile本身直接列出的宝石才有。

此外,Bundle.require可能不需要某些Bundler组中包含的宝石,例如' development',即使它们直接包含在Gemfile中,您需要告诉bundler需要非默认组。

您可以随时手动require gems,例如require 'rails'。对于Gemfile中的每个gem(或者至少是Gemfile中的默认组),Bundle.require除了require gem之外什么都不做,除了查找所有宝石之外,它还在做任何魔术在您的Gemfile中并要求它们。有些人认为Bundle.require被一些人认为是一种不好的做法,你应该只需要你需要的文件中所需的依赖项。虽然Rails不同意,但Rails应用程序有自己的一些复杂的自动加载方式。

但是如果你在Rails应用程序中,因为你的示例依赖项建议...为什么你自己在做任何require 'bundler/setup'Bundle.require,而不是让Rails引导过程照顾它? Rails引导过程将负责处理您可能期望的Bundler组(如Rails.env == 'development'中的"开发"组)。

可以直接使用自己的捆绑API,就像你做的那样,它并不太难。但是Rails通常会为你处理这个问题,如果你正在使用Rails,那么rails可能已经完成了Bundler.setupBundler.require作为Rails启动过程的一部分。