Que signifie «exiger: faux» dans Gemfile?

429

Est ce que ca:

gem 'whenever', require: false

signifie que la gemme doit être installée, ou cela signifie-t-il qu'elle n'est pas requise?

rafamvc
la source
1
La plupart des réponses (y compris celles acceptées) concernent les Rails qui font Bundler.requirepar défaut ce que je comprends. Seules les réponses de Ciro et Nesha sont correctes.
Nakilon

Réponses:

472

Cela signifie installer la gemme, mais n'appelez pas require lorsque vous démarrez Bundler. Vous devrez donc appeler manuellement

require "whenever"

si vous souhaitez utiliser la bibliothèque.

Si tu devais faire

gem "whenever", require: "whereever"

alors bundler téléchargerait la gemme nommée à chaque fois, mais appellerait

require "whereever"

Ceci est souvent utilisé si le nom de la bibliothèque à exiger est différent du nom de la gemme.

Rob Di Marco
la source
112
@VenkatD. Parfois, vous voulez installer certaines gemmes mais vous ne voulez pas les charger dans chaque processus. J'ai une tâche de râteau particulière que je veux invoquer périodiquement sur Heroku via leur module complémentaire programmé. Cette tâche de râteau particulière nécessite certaines gemmes dont le reste de l'application n'a pas besoin. J'ai donc :require => falseces joyaux particuliers et explicitement require "thegem"de la tâche de râteau. Cela permettrait alors d'économiser de la mémoire dans les processus d'application principaux et le temps de démarrage, etc. Les performances de l'application, cependant, ne devraient pas être affectées même si vous avez besoin de ces gemmes supplémentaires dans chaque processus.
Michael van Rooijen
5
@MichaelvanRooijen - cependant, de grands points: "Les performances de l'application, cependant, ne devraient pas être affectées même si vous avez besoin de ces gemmes supplémentaires dans chaque processus". Je ne pense pas que ce soit vrai. L'allocation d'objets prend du travail, et le GC doit les parcourir tous à chaque fois, donc plus = plus lentement, selon confreaks.com/videos/2668-gogaruco2013-measuring-ruby
Nathan Long
1
@MichaelvanRooijen - En pratique, vous avez raison, cela n'a généralement pas d'importance à moins que vous n'utilisiez la bibliothèque. Mais nécessiter un bijou chargera au moins son fichier principal dans lib, et probablement il en fait plus lui-même. Même si vous require 'yaml', vous avez maintenant le YAMLmodule en tant qu'objet en mémoire.
Nathan Long
2
Que faire si vous souhaitez définir la valeur false sur false et que le nom de la bibliothèque est également différent du nom de la gemme?
Peter-Jan Celis
2
@ Peter-JanCelis Dans ce cas, vous devez simplement définir :require => false, puis dans votre code, avoirrequire 'library_name_here'
Rob Di Marco
73

Vous utilisez :require => falsequand vous voulez que la gemme soit installée mais pas "requise".

Ainsi, dans l'exemple que vous avez donné: gem 'whenever', :require => false lorsque quelqu'un exécute l'installation de bundle, la gemme à chaque fois doit être installée comme avec gem install whenever. Chaque fois qu'il est utilisé pour créer des tâches cron en exécutant une tâche de râteau, mais n'est généralement pas utilisé à partir de l'application rails (ou autre structure si ce n'est rails).

Vous pouvez donc utiliser :require => falsepour tout ce que vous devez exécuter à partir de la ligne de commande mais dont vous n'avez pas besoin dans votre code.

gduq
la source
6
Cela pourrait également être utilisé pour une gemme que vous n'utilisez que dans un petit sous-ensemble de demandes.
Nathan Long
61

require: falseindique de Bundler.requirene pas exiger cette gemme spécifique: la gemme doit être demandée explicitement via require 'gem'.

Cette option n'affecte pas :

  • bundle install: la gemme sera installée malgré tout

  • la requireconfiguration du chemin de recherche par bundler.

    Bundler ajoute des éléments au chemin lorsque vous effectuez l'une des opérations suivantes:

    • Bundle.setup
    • qui est appelé par require bundler/setup
    • qui est appelé par bundle exec

Exemple

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

Ensuite, les éléments suivants ne déclencheront pas d'exceptions:

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

Sur GitHub pour que vous puissiez jouer avec.

Utilisation des rails

Comme expliqué dans le tutoriel d'initialisation , le modèle Rails par défaut s'exécute au démarrage:

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

config/boot.rb contient:

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

qui fait le require 'bundler/setup'et configure le chemin requis.

config/application.rb Est-ce que:

Bundler.require(:default, Rails.env)

qui nécessite en fait les gemmes.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
Notez que l'utilisation require 'fakerpeut ne pas utiliser la bonne version de gemme, en particulier si vous êtes Gemfile pointe vers une référence git.
dazonic
@dazonic Haml est-il différent sur l'exemple?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
9

Chaque fois que vous spécifiez une gemme dans votre Gemfileexécution bundle install, bundler ira installer la gemme spécifiée et chargera le code pour cette gemme dans votre application en mettant de require 'whenever'cette façon bundler chargera le code pour toutes vos gemmes dans votre application Rails, et vous pouvez appeler n'importe quelle méthode de n'importe quel bijou sans aucune douleur, comme vous le faites la plupart du temps.

mais les gemmes comme whenever, faker or capistrano sont quelque chose dont vous n'avez pas besoin dans votre code d'application dont vous avez besoin chaque fois que du code dans votre schedule.rb fichier pour gérer les codes crons et capistrano dans le deploy.rb fichier pour personnaliser la recette de déploiement, vous n'avez donc pas besoin de charger le code de ces gemmes dans votre code d'application et où que vous soyez voulez appeler n'importe quelle méthode à partir de ces gemmes, vous pouvez manuellement exiger ces gemmes par vous-même en les mettant require "whenever" . Donc, vous mettez :require => falsevotre Gemfile pour ces gemmes, de cette façon le bundle installera cette gemme mais ne chargera pas le code pour cette gemme elle-même, vous pouvez le faire quand vous le souhaitez en mettant simplement comme exiger "à chaque fois" dans votre cas.

Subhash Chandra
la source
2

Afin d'exiger des gemmes dans votre Gemfile, vous devrez appeler Bundler.require.

Vous pouvez empêcher Bundler d'exiger la gemme avec require: false, mais il installera et maintiendra toujours la gemme. Vérifiez ceci pour une explication plus détaillée.

Nesha Zoric
la source