我应该使用“bundle exec”还是 Rails 的 binstub?

x-y*_*uri 7 ruby-on-rails bundler

假设我有一个 Rails 应用程序,其中安装了 gems bundler。我应该使用bundle exec rails还是bin/rails?我应该使用bundle exec rake还是bin/rake?有什么区别吗?其中任何一个比另一个更好吗?

x-y*_*uri 7

太长了;博士没有特别的区别,但如果我要选择,我会使用bin/rails

几乎没有区别。让我们来看看。

DISABLE_SPRING=1 bin/rails --version:

bin/rails::::::::::​​​​​​​require_relative '../config/boot'
config/bootrequire 'bundler/setup'
bundler/setupBundler.setup
Bundler.setupdefinition.validate_runtime!
Bundler.definitionDefinition.build
Bundler::Definition.buildDsl.evaluate
Bundler::Dsl.evaluatebuilder.eval_gemfile
Bundler::Dsl#eval_gemfileinstance_eval

之后require 'bundler/setup',尝试gem 'rails', 'x.y.z'得到:

*** Gem::LoadError 异常:无法激活rails (= xyz),已激活rails-5.1.3。确保所有依赖项都添加到 Gemfile 中。

有了bundle exec rails --version,我们最终运行bin/rails:

~/.gem/ruby/x.y.z/bin/rails:::::​​​load Gem.activate_bin_path('railties', 'rails', version)
exe/railsrequire 'rails/cli'
rails/cliRails::AppLoader.exec_app
Rails::AppLoader.exec_app exec RUBY, 'bin/rails', *ARGV

另外,请注意在最后一个文件中可以找到的消息:

从 Rails 4 开始,Rails 附带了rails位于 ./bin/rails 的 binstub,应该使用它来代替 Bundler 生成的 binstubrailsbinstub。

所以,归根结底,没有什么区别。但考虑到 Rails 经历了运送自己的 binstubs 的麻烦这一事实,我更倾向于bin/rails替代方案。此外,它的自动完成功能也更好。

和,

应用程序可执行文件现在位于bin/目录:bin/bundle, bin/rails, bin/rake. 跑步rake rails:update:bin以将这些可执行文件添加到您自己的应用程序中。script/rails已从新应用程序中消失。

在应用程序中运行可执行文件可确保它们使用应用程序的 Ruby 版本及其捆绑的 gem,并确保您的生产部署工具仅需要执行单个脚本。不再需要小心翼翼cd进入应用程序目录并运行bundle exec ...。

捆绑器 1.3没有将其视为bin/生成的“binstub”的垃圾抽屉,而是添加了对仅为您实际使用的可执行文件生成存根的支持:bundle binstubs unicorngenerates bin/unicorn。将该可执行文件添加到 git 并对其进行版本控制,就像任何其他应用程序代码一样。

https://github.com/rails/rails/blob/4-0-stable/railties/CHANGELOG.md


Per*_*ell 5

bundle exec只需确保运行命令时 Gemfile 中的所有 gem 都已安装(全局或用户空间或vendor/bundle项目目录中)。https://bundler.io/man/bundle-exec.1.html(特别是https://bundler.io/man/bundle-exec.1.html#BUNDLE-INSTALL-BINSTUBS部分)中有更详细的解释:

捆绑安装--binstubs

如果您在 中使用该--binstubs标志bundle install,Bundler 将自动创建一个目录(默认为app_root/bin),其中包含捆绑包中 gems 可用的所有可执行文件。

使用后--binstubs,bin/rspec spec/my_spec.rb与 相同 bundle exec rspec spec/my_spec.rb。

Binstubs 还可能包括其他自定义,例如加载springgem,它可以预加载并加速 Rails 应用程序。