ruby-on-rails 我应该使用'bundle exec'还是Rails的binstub?

yx2lnoni  于 2023-01-27  发布在  Ruby
关注(0)|答案(4)|浏览(176)

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

7vhp5slm

7vhp5slm1#

    • tl; dr**没有特别的区别,但如果要我选择,我会使用bin/rails

几乎没有区别。让我们看看。
DISABLE_SPRING=1 bin/rails --version
bin/railsrequire_relative '../config/boot'
config/bootrequire 'bundler/setup'
bundler/setupBundler.setup
Bundler.setupdefinition.validate_runtime!
一个月十个月一个月:一个月十一个月一个月
一个月十二个月一个月:一个月十三个月一个月
一个月十四个月一个月:一个月十五个月一个月
一个月十六个月一个月:一个月十七个月一个月
require 'bundler/setup'之后,尝试gem 'rails', 'x.y.z'会导致:

***Gem::加载错误异常:无法激活rails(= x.y. z),已激活rails-5.1.3。请确保所有依赖项都已添加到Gemfile。

对于bundle exec rails --version,我们最终还是运行了bin/rails
一个月二十二个月一个月:一个月二十三个月一个月
一个月二十四个月一个月:一个月二十五个月一个月
一个月二十六个月一个月:一个月二十七个月一个月
Rails::AppLoader.exec_app:'执行RUBY,'箱/轨道',* ARGV
此外,请注意在最后一个文件中可以找到的消息:
从Rails 4开始,Rails在./bin/rails中附带了一个rails binstub,应该使用它来代替Bundler生成的rails binstub。
所以,在一天结束的时候,没有什么不同。但是考虑到Rails在发布自己的binstub时遇到了麻烦,我更喜欢bin/rails替代品。而且,它的自动完成功能更好。
还有
应用程序可执行文件现在位于bin/目录中:bin/bundlebin/railsbin/rake。运行rake rails:update:bin以将这些可执行文件添加到你自己的应用。script/rails已从新应用中删除。
在您的应用中运行可执行文件可确保它们使用您的应用的Ruby版本及其捆绑的gem,并确保您的生产部署工具仅需执行单个脚本。无需再小心地将cd转到应用目录并运行bundle exec ...
Bundler 1.3没有将bin/视为生成"binstub"的垃圾抽屉,而是增加了对只为实际使用的可执行文件生成存根的支持:bundle binstubs unicorn生成bin/unicorn。将该可执行文件添加到git并像其他应用代码一样对其进行版本控制。
https://github.com/rails/rails/blob/4-0-stable/railties/CHANGELOG.md

osh3o9ms

osh3o9ms2#

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部分):

捆绑包安装--binstub

如果您在bundle install中使用--binstubs标志,Bundler将自动创建一个目录(默认为app_root/bin),其中包含该包中gem提供的所有可执行文件。
在使用--binstubs之后,bin/rspec spec/my_spec.rbbundle exec rspec spec/my_spec.rb相同。
Binstub还可以包含其他定制,如加载spring gem,它可以预加载Rails应用程序并提高其速度。

ibrsph3r

ibrsph3r3#

这些答案中没有基准测试,使用hyperfine我们可以了解使用任一选项加载Rails所需的时间。
下面的测试是在Ruby3.2.0上执行的,在Rails7上启用了YJIT。使用它们作为指导,使用您自己的Rails应用程序运行您自己的基准测试,以确定在性能重要的情况下使用哪个脚本。
∮ ∮ ∮ ∮ ∮一个月一个月

$ hyperfine --runs 40 --warmup 10 "bundle exec rails --version"
Benchmark 1: bundle exec rails --version
  Time (mean ± σ):     487.9 ms ±  11.6 ms    [User: 305.1 ms, System: 112.3 ms]
  Range (min … max):   470.9 ms … 520.2 ms    40 runs

一米一分一秒

$ hyperfine --runs 40 --warmup 10 "bin/rails --version"
Benchmark 1: bin/rails --version
  Time (mean ± σ):     337.5 ms ±  10.5 ms    [User: 189.2 ms, System: 78.7 ms]
  Range (min … max):   317.8 ms … 372.0 ms    40 runs

赢家:bin/rails

150ms并没有太大的区别,但在 Boot 时间绝对重要的系统中可能会很重要。
为什么会有区别呢?这取决于每个脚本的作用:

bin/rails

#!/usr/bin/env ruby
APP_PATH = File.expand_path("../config/application", __dir__)
require_relative "../config/boot"
require "rails/commands"

一米四分一秒

#!/usr/bin/env ruby
#
# This file was generated by RubyGems.
#
# The application 'railties' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

Gem.use_gemdeps

version = ">= 0.a"

str = ARGV.first
if str
  str = str.b[/\A_(.*)_\z/, 1]
  if str and Gem::Version.correct?(str)
    version = str
    ARGV.shift
  end
end

if Gem.respond_to?(:activate_bin_path)
load Gem.activate_bin_path('railties', 'rails', version)
else
gem "railties", version
load Gem.bin_path("railties", "rails", version)
end

bundler使用的脚本做的事情比较多,所以运行的时间比较长。在一个正确配置的应用程序中,任何一个脚本都可以正常工作,所以唯一需要关注的应该是性能,如果它很重要的话。

sd2nnvve

sd2nnvve4#

Bundle exec是Bundler命令。
在所有情况下都应该使用bundle exec,因为它
bundle-exec -在包的上下文中执行命令
更多信息可在此处找到:http://bundler.io/v1.15/bundle_exec.html
bin/rails可能会起作用,但前提是所有必需的gem/可执行文件都存在于您的系统上,而不受捆绑包的影响。
简而言之,如果你的系统上安装了所有的gem(例如全局安装),bin/rails就可以工作(但是可能会产生冲突),但是如果你只在bundle的范围内安装它们,它们可能就不能工作了。
bundle exec可确保使用宝石文件中的宝石及其版本。

相关问题