我应该使用 `bundle exec` 还是 Rails' binstubs?
Should I use `bundle exec` or Rails' binstubs?
假设我有一个 Rails 应用程序,其中安装了 bundler
的 gems。我应该使用 bundle exec rails
还是 bin/rails
?我应该使用 bundle exec rake
还是 bin/rake
?有什么不同吗?哪一个比另一个好?
Bundle exec 是一个 Bundler 命令。
您应该在所有情况下都使用 bundle exec
bundle-exec - Execute a command in the context of the bundle
可在此处找到更多信息:http://bundler.io/v1.15/bundle_exec.html
bin/rails 可能会起作用,但前提是所有必需的 gems/executables 都存在于您的系统上且不在捆绑范围内。
简而言之,如果您在系统上安装了所有 gem(例如,全局),bin/rails 将起作用(但可能会产生冲突)。但是,如果您仅将它们安装在捆绑包的范围内,它们可能无法工作。
bundle exec
确保使用 Gemfile 中的 gem 及其版本。
tl;dr 没有特别的区别,但如果让我选择,我会使用 bin/rails
几乎没有区别。让我们看看。
DISABLE_SPRING=1 bin/rails --version
:
bin/rails
: require_relative '../config/boot'
config/boot
: require 'bundler/setup'
bundler/setup
: Bundler.setup
Bundler.setup
: definition.validate_runtime!
Bundler.definition
: Definition.build
Bundler::Definition.build
: Dsl.evaluate
Bundler::Dsl.evaluate
: builder.eval_gemfile
Bundler::Dsl#eval_gemfile
: instance_eval
在 require 'bundler/setup'
之后尝试 gem 'rails', 'x.y.z'
结果:
*** Gem::LoadError Exception: can't activate rails (= x.y.z), already activated rails-5.1.3. Make sure all dependencies are added to Gemfile.
有了 bundle exec rails --version
,我们最终得到 运行 bin/rails
无论如何:
~/.gem/ruby/x.y.z/bin/rails
: load Gem.activate_bin_path('railties', 'rails', version)
exe/rails
: require 'rails/cli'
rails/cli
: Rails::AppLoader.exec_app
Rails::AppLoader.exec_app
: `exec RUBY, 'bin/rails', *ARGV
此外,请注意可以在 last file:
中找到的消息
Beginning in Rails 4, Rails ships with a rails
binstub at ./bin/rails that should be used instead of the Bundler-generated rails
binstub.
所以,归根结底,没有什么区别。但考虑到 Rails 经历了运送自己的 binstub 的麻烦这一事实,我更倾向于 bin/rails
替代方案。此外,它的自动完成效果更好。
并且,
App executables now live in the bin/
directory: bin/bundle
, bin/rails
, bin/rake
. Run rake rails:update:bin
to add these executables to your own app. script/rails
is gone from new apps.
Running executables within your app ensures they use your app's Ruby version and its bundled gems, and it ensures your production deployment tools only need to execute a single script. No more having to carefully cd
to the app dir and run bundle exec ...
.
Rather than treating bin/
as a junk drawer for generated "binstubs", bundler 1.3 adds support for generating stubs for just the executables you actually use: bundle binstubs unicorn
generates bin/unicorn
. Add that executable to git and version it just like any other app code.
https://github.com/rails/rails/blob/4-0-stable/railties/CHANGELOG.md
bundle exec
只是确保在 运行 命令时 Gemfile 中的所有 gem 都已安装(全局或在用户空间或在项目的 vendor/bundle
目录中)。 https://bundler.io/man/bundle-exec.1.html (especifically https://bundler.io/man/bundle-exec.1.html#BUNDLE-INSTALL-BINSTUBS 部分有更详细的解释):
Bundle Install --binstubs
If you use the --binstubs
flag in bundle install
, Bundler will automatically create a directory (which defaults to app_root/bin
) containing all of the executables available from gems in the bundle.
After using --binstubs
, bin/rspec spec/my_spec.rb
is identical to
bundle exec rspec spec/my_spec.rb
.
Binstubs 可能还包括其他自定义设置,例如加载 spring
gem,它会预加载并加速 Rails 应用程序。
假设我有一个 Rails 应用程序,其中安装了 bundler
的 gems。我应该使用 bundle exec rails
还是 bin/rails
?我应该使用 bundle exec rake
还是 bin/rake
?有什么不同吗?哪一个比另一个好?
Bundle exec 是一个 Bundler 命令。
您应该在所有情况下都使用 bundle exec
bundle-exec - Execute a command in the context of the bundle
可在此处找到更多信息:http://bundler.io/v1.15/bundle_exec.html
bin/rails 可能会起作用,但前提是所有必需的 gems/executables 都存在于您的系统上且不在捆绑范围内。
简而言之,如果您在系统上安装了所有 gem(例如,全局),bin/rails 将起作用(但可能会产生冲突)。但是,如果您仅将它们安装在捆绑包的范围内,它们可能无法工作。
bundle exec
确保使用 Gemfile 中的 gem 及其版本。
tl;dr 没有特别的区别,但如果让我选择,我会使用 bin/rails
几乎没有区别。让我们看看。
DISABLE_SPRING=1 bin/rails --version
:
bin/rails
: require_relative '../config/boot'
config/boot
: require 'bundler/setup'
bundler/setup
: Bundler.setup
Bundler.setup
: definition.validate_runtime!
Bundler.definition
: Definition.build
Bundler::Definition.build
: Dsl.evaluate
Bundler::Dsl.evaluate
: builder.eval_gemfile
Bundler::Dsl#eval_gemfile
: instance_eval
在 require 'bundler/setup'
之后尝试 gem 'rails', 'x.y.z'
结果:
*** Gem::LoadError Exception: can't activate rails (= x.y.z), already activated rails-5.1.3. Make sure all dependencies are added to Gemfile.
有了 bundle exec rails --version
,我们最终得到 运行 bin/rails
无论如何:
~/.gem/ruby/x.y.z/bin/rails
: load Gem.activate_bin_path('railties', 'rails', version)
exe/rails
: require 'rails/cli'
rails/cli
: Rails::AppLoader.exec_app
Rails::AppLoader.exec_app
: `exec RUBY, 'bin/rails', *ARGV
此外,请注意可以在 last file:
中找到的消息Beginning in Rails 4, Rails ships with a
rails
binstub at ./bin/rails that should be used instead of the Bundler-generatedrails
binstub.
所以,归根结底,没有什么区别。但考虑到 Rails 经历了运送自己的 binstub 的麻烦这一事实,我更倾向于 bin/rails
替代方案。此外,它的自动完成效果更好。
并且,
App executables now live in the
bin/
directory:bin/bundle
,bin/rails
,bin/rake
. Runrake rails:update:bin
to add these executables to your own app.script/rails
is gone from new apps.Running executables within your app ensures they use your app's Ruby version and its bundled gems, and it ensures your production deployment tools only need to execute a single script. No more having to carefully
cd
to the app dir and runbundle exec ...
.Rather than treating
bin/
as a junk drawer for generated "binstubs", bundler 1.3 adds support for generating stubs for just the executables you actually use:bundle binstubs unicorn
generatesbin/unicorn
. Add that executable to git and version it just like any other app code.
https://github.com/rails/rails/blob/4-0-stable/railties/CHANGELOG.md
bundle exec
只是确保在 运行 命令时 Gemfile 中的所有 gem 都已安装(全局或在用户空间或在项目的 vendor/bundle
目录中)。 https://bundler.io/man/bundle-exec.1.html (especifically https://bundler.io/man/bundle-exec.1.html#BUNDLE-INSTALL-BINSTUBS 部分有更详细的解释):
Bundle Install --binstubs
If you use the
--binstubs
flag inbundle install
, Bundler will automatically create a directory (which defaults toapp_root/bin
) containing all of the executables available from gems in the bundle.After using
--binstubs
,bin/rspec spec/my_spec.rb
is identical tobundle exec rspec spec/my_spec.rb
.
Binstubs 可能还包括其他自定义设置,例如加载 spring
gem,它会预加载并加速 Rails 应用程序。