Что значит 'require: false' в Gemfile?

429

Является ли это:

gem 'whenever', require: false

означает, что драгоценный камень должен быть установлен, или это означает, что он не требуется?

rafamvc
источник
1
Большинство ответов (включая принятый) касаются Rails, которые, Bundler.requireкак я понимаю , делают по умолчанию. Только ответы Сиро и Нешы верны.
Накилон

Ответы:

472

Это означает, что нужно установить гем, но не вызывать require при запуске Bundler. Так что вам нужно будет позвонить вручную

require "whenever"

если вы хотите использовать библиотеку.

Если бы вы должны были сделать

gem "whenever", require: "whereever"

тогда bundler будет загружать гем, названный в любое время, но будет вызывать

require "whereever"

Это часто используется, если имя требуемой библиотеки отличается от имени драгоценного камня.

Роб Ди Марко
источник
112
@VenkatD. иногда вы хотите установить определенные гемы, но не хотите загружать их в каждый процесс. У меня есть конкретное задание по рейку, которое я хочу периодически вызывать на Heroku через их надстройку по расписанию. Эта конкретная задача с граблями требует определенных драгоценных камней, которые не нужны остальной части приложения. Так что я :require => falseэти конкретные драгоценные камни и явно require "thegem"из грабли задачи. Это позволит сэкономить память в основных процессах приложения и времени запуска и т. Д. Однако на производительность приложения не следует влиять, даже если вам требуются эти дополнительные гемы в каждом процессе.
Майкл ван Ройен
5
@MichaelvanRooijen - отличные замечания, однако: «Однако на производительность приложения не следует влиять, даже если вам нужны эти дополнительные драгоценные камни в каждом процессе». Я не думаю, что это правда. Распределение объектов требует работы, и GC должен каждый раз проходить через них, так что больше = медленнее, согласно confreaks.com/videos/2668-gogaruco2013-measuring-ruby
Натан Лонг,
1
@MichaelvanRooijen - На практике вы правы, это не имеет значения, если вы не используете библиотеку. Но требование гема по крайней мере загрузит его основной файл в lib, и, вероятно, он требует больше своих собственных. Даже если вы require 'yaml', теперь у вас есть YAMLмодуль как объект в памяти.
Натан Лонг
2
Что если вы хотите установить для параметра false значение false, а имя библиотеки также отличается от имени гема?
Питер-Ян Селис
2
@ Peter-JanCelis В этом случае вы просто должны установить, :require => falseа затем в своем коде естьrequire 'library_name_here'
Роб Ди Марко
73

Вы используете, :require => falseкогда хотите, чтобы гем был установлен, но не «требуется».

Таким образом , в этом примере вы дали: gem 'whenever', :require => false когда кто - то бежит Bundle установить всякий раз , когда камень будет установлен как с gem install whenever. Всякий раз, когда используется для создания заданий cron путем запуска задачи rake, но обычно не используется из приложения rails (или другой платформы, если не rails).

Таким образом, вы можете использовать :require => falseвсе, что вам нужно для запуска из командной строки, но не нужно в вашем коде.

gduq
источник
6
Это также может быть использовано для драгоценного камня, который вы используете только в небольшом подмножестве запросов.
Натан Лонг
61

require: falseговорит Bundler.requireне требовать этот конкретный драгоценный камень: драгоценный камень должен требоваться явно через require 'gem'.

Эта опция не влияет на:

  • bundle install: драгоценный камень будет установлен независимо

  • requireустановка пути поиска по Bundler.

    Bundler добавляет вещи к пути, когда вы делаете одно из:

    • Bundle.setup
    • который называется require bundler/setup
    • который называется bundle exec

пример

Gemfile

source 'https://rubygems.org'
gem 'haml'
gem 'faker', require: false

main.rb

# Fail because we haven't done Bundler.require yet.
# bundle exec does not automatically require anything for us,
# it only puts them in the require path.
begin Haml; rescue NameError; else raise; end
begin Faker; rescue NameError; else raise; end

# The Bundler object is automatically required on `bundle exec`.
Bundler.require

Haml
# Not required because of the require: false on the Gemfile.
# THIS is what `require: false` does.
begin Faker; rescue NameError; else raise; end

# Faker is in the path because Bundle.setup is done automatically
# when we use `bundle exec`. This is not affected by `require: false`.
require 'faker'
Faker

Тогда следующее не вызовет исключения:

bundle install --path=.bundle
bundle exec ruby main.rb

На GitHub для вас играть с ним.

Использование Rails

Как объяснено в руководстве по инициализации , шаблон Rails по умолчанию запускается при запуске:

  • config/boot.rb
  • config/application.rb

config/boot.rb содержит:

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

который делает require 'bundler/setup'и устанавливает требуемый путь.

config/application.rb делает:

Bundler.require(:default, Rails.env)

который на самом деле требует драгоценных камней.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
источник
Обратите внимание, что использование require 'fakerможет не использовать правильную версию gem, особенно если вы указываете Gemfile на git ref.
августа
@dazonic Хэмл отличается от примера?
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功
9

Всякий раз, когда вы указываете Gem в вашем Gemfileи запускаете bundle install, bundler будет запускать и устанавливать указанный Gem и загружать код для этого Gem в ваше приложение, устанавливая require 'whenever'этот способ, чтобы bundler загружал код для всех ваших Gem в ваше приложение Rails, и вы можете вызывать любой метод. из любого драгоценного камня без какой-либо боли, как вы делаете большую часть времени.

но Gems like whenever, faker or capistrano - это то, что вам не нужно в коде приложения, которое вам нужно всякий раз, когда код в вашем schedule.rb файле управляет кодами cron и capistrano в deploy.rb файле для настройки рецепта развертывания, поэтому вам не нужно загружать код для этих драгоценных камней в код вашего приложения и куда бы вы ни шли Если вы хотите вызвать любой метод из этих самоцветов, вы можете вручную запросить эти самоцветы, поставив require "whenever" . таким образом, вы вставляете :require => falseсвой Gemfile для этих Gems, таким образом, упаковщик будет устанавливать этот Gem, но не загружать код для этого самого Gem, вы можете сделать это в любое время, просто вставив в вашем случае команду require 'when'.

Субхаш Чандра
источник
2

Чтобы потребовать драгоценные камни в вашем Gemfile, вам нужно будет позвонить Bundler.require.

Вы можете запретить сборщику запрашивать драгоценный камень require: false, но он все равно будет устанавливать и поддерживать драгоценный камень. Проверьте это для более подробного объяснения.

Неша Зорич
источник