Docs header transparent bg

gemfile

Gemfile - 用於描述 Ruby 程式 gem 相依性的格式

A Gemfile describes the gem dependencies required to execute associated
Ruby code.

Gemfile 放置在包含相關程式碼的目錄根目錄中。例如,在 Rails 應用程式中,將 Gemfile 放置在與 Rakefile 相同的目錄中。

語法

Gemfile 會被評估為 Ruby 程式碼,在一個可用來描述 gem 需求的許多方法的背景下。

全域來源

Gemfile 的最上方,新增一行 RubyGems 來源,其中包含 Gemfile 中所列的 gem。

source "https://rubygems.org"

您只能新增一個全域來源。在 Bundler 1.13 中,新增多個全域來源已被棄用。source 必須 是有效的 RubyGems 存放庫。

若要使用多個 RubyGems 來源,您應該使用 source 區塊

會根據 來源優先順序 中所述的啟發法,檢查來源中的 gem。

關於 Bundler 1.13 中已棄用功能的行為注意事項:如果在多個全域來源中找到 gem,Bundler 會在安裝 gem 之後印出警告,指出使用哪個來源,並列出 gem 可用的其他來源。可以透過使用 :source 選項source 區塊,為需要使用非標準存放庫的 gem 選擇特定來源,以抑制此警告。

認證

有些 gem 來源需要使用者名稱和密碼。使用 bundle config(1) 為需要它的任何來源設定使用者名稱和密碼。必須在每台將安裝 Gemfile 的電腦上執行一次命令,但這可避免將認證資料以純文字儲存在版本控制中。

bundle config gems.example.com user:password

對於某些來源,例如公司 Gemfury 帳戶,將認證資料包含在 Gemfile 中,作為來源 URL 的一部分,可能會比較容易。

source "https://user:password@gems.example.com"

來源 URL 中的認證資料將優先於使用 config 設定的認證資料。

Ruby

如果您的應用程式需要特定的 Ruby 版本或引擎,請使用 ruby 方法,並使用下列引數指定您的需求。除非另有說明,否則所有參數都是 選用 的。

版本(必填)

應用程式所需的 Ruby 版本。如果應用程式需要其他 Ruby 引擎,例如 JRuby、TruffleRuby 等,則此處應為與該引擎相容的 Ruby 版本。

ruby "3.1.2"

如果您希望從版本檔案(例如 .ruby-version)衍生 Ruby 版本,則可以使用 file 選項。

ruby file: ".ruby-version"

版本檔案應符合下列格式之一

  • 3.1.2 (.ruby-version)
  • ruby 3.1.2 (.tool-versions,閱讀:https://asdf-vm.com/manage/configuration.html#tool-versions)

引擎

每個應用程式可以指定 Ruby 引擎。如果指定引擎,則必須同時指定引擎版本。

引擎究竟是什麼?

  • Ruby 引擎是 Ruby 語言的實作。

  • 背景知識:Ruby 程式語言的參考或原始實作稱為 Matz's Ruby Interpreter,簡稱 MRI。此名稱來自 Ruby 建立者 Yukihiro Matsumoto,又稱 Matz。MRI 也稱為 CRuby,因為它是用 C 編寫的。MRI 是使用最廣泛的 Ruby 引擎。

  • Ruby 還有 其他實作。一些較知名的實作包括 JRubyTruffleRuby。Rubinius 是用 Ruby 編寫的 Ruby 替代實作。JRuby 是在 JVM(Java 虛擬機器)上的 Ruby 實作。TruffleRuby 是在 GraalVM(建構在 JVM 上的語言工具組)上的 Ruby 實作。

引擎版本

每個應用程式可以指定 Ruby 引擎版本。如果指定引擎版本,則必須同時指定引擎。如果引擎為「ruby」,則指定的引擎版本必須與 Ruby 版本相符。

ruby "2.6.8", engine: "jruby", engine_version: "9.3.8.0"

修補程式等級

每個應用程式可以指定 Ruby 修補程式等級。自 Ruby 2.1.0 發布以來,指定修補程式等級已無意義,因為修補程式等級現在由主要、次要和次次要版本號碼的組合唯一決定。

此選項在 Ruby 2.0 或更早版本中實作於 Bundler 1.4.0。

ruby "3.1.2", patchlevel: "20"

寶石

使用 gem 方法指定寶石需求,並附上下列參數。除非另有說明,否則所有參數均為 OPTIONAL

名稱(必填)

對於每個寶石需求,請列出單一寶石行。

gem "nokogiri"

版本

每個寶石MAY 有多個版本規範。

gem "nokogiri", ">= 1.4.2"
gem "RedCloth", ">= 4.1.0", "< 4.2.0"

需求為

每個寶石MAY 指定在透過 Bundler.require 自動需求時應使用的檔案。您可以傳遞包含多個檔案的陣列,或如果要 required 的檔案與寶石同名,則傳遞 true,或傳遞 false 以防止任何檔案自動需求。

gem "redis", require: ["redis/connection/hiredis", "redis"]
gem "webmock", require: false
gem "byebug", require: true

參數預設為寶石名稱。例如,下列兩者相同

gem "nokogiri"
gem "nokogiri", require: "nokogiri"
gem "nokogiri", require: true

群組

每個寶石MAY 指定屬於一個或多個群組。未指定屬於任何群組的寶石將置於 default 群組中。

gem "rspec", group: :test
gem "wirble", groups: [:development, :test]

Bundler 執行時期允許其兩個主要方法,Bundler.setupBundler.require,將其影響限制在特定群組。

# setup adds gems to Ruby's load path
Bundler.setup                    # defaults to all groups
require "bundler/setup"          # same as Bundler.setup
Bundler.setup(:default)          # only set up the _default_ group
Bundler.setup(:test)             # only set up the _test_ group (but `not` _default_)
Bundler.setup(:default, :test)   # set up the _default_ and _test_ groups, but no others

# require requires all of the gems in the specified groups
Bundler.require                  # defaults to the _default_ group
Bundler.require(:default)        # identical
Bundler.require(:default, :test) # requires the _default_ and _test_ groups
Bundler.require(:test)           # requires the _test_ group

Bundler CLI 允許您指定一組群組,bundle install 不應使用 without 設定檔安裝其 gem。

若要指定多個要忽略的群組,請指定由空格分隔的群組清單。

bundle config set --local without test
bundle config set --local without development test

此外,呼叫沒有參數的 Bundler.setup,或呼叫 require "bundler/setup" 將設定所有群組,但排除您透過 --without 排除的群組(因為它們不可用)。

請注意,在 bundle install 上,bundler 下載並評估所有 gem,以便建立所有所需 gem 及其依賴項目的單一正規清單。這表示您無法在不同群組中列出相同 gem 的不同版本。如需更多詳細資訊,請參閱 了解 Bundler

平台

如果 gem 僅應在特定平台或平台組中使用,您可以指定它們。平台基本上與群組相同,但您不需要使用安裝時間旗標 --without 排除其他平台的 gem 群組。

有許多 Gemfile 平台

ruby
C Ruby (MRI)、Rubinius 或 TruffleRuby,但不是 Windows
mri
僅限 C Ruby (MRI),但不是 Windows
windows
Windows C Ruby (MRI),包括 RubyInstaller 32 位元和 64 位元版本
mswin
Windows C Ruby (MRI),包括 RubyInstaller 32 位元版本
mswin64
Windows C Ruby (MRI),包括 RubyInstaller 64 位元版本
rbx
Rubinius
jruby
JRuby
truffleruby
TruffleRuby

在平台 rubymrimswinmswin64windows 上,您還可以透過附加主次版本號碼(沒有分隔符號)來指定版本。例如,若要指定 gem 僅應在平台 ruby 版本 3.1 上使用,請使用

ruby_31

與群組(如上所述)一樣,您可以指定一個或多個平台

gem "weakling",   platforms: :jruby
gem "ruby-debug", platforms: :mri_31
gem "nokogiri",   platforms: [:windows_31, :jruby]

涉及群組的所有操作(bundle installBundler.setupBundler.require)的行為完全相同,就像任何與目前平台不符的群組都明確排除了一樣。

以下平台值已棄用,應以 windows 取代

  • mswinmswin64mingw32x64_mingw

Force_ruby_platform

如果您總是希望選擇 gem 的純 ruby 變體,而不是特定於平台的變體,您可以使用 force_ruby_platform 選項

gem "ffi", force_ruby_platform: true

這可能很方便(假設純 ruby 變體運作良好),當

  • 您遇到平台特定變體的問題。
  • 平台特定變體尚未支援較新的 Ruby(因此具有 required_ruby_version 上限),但您仍希望 Gemfile{.lock} 檔案在該 Ruby 下解析。

來源

您可以使用「:source」選項為寶石選擇備用的 RubyGems 存放庫。

gem "some_internal_gem", source: "https://gems.example.com"

這會強制從此來源載入寶石,並忽略檔案頂層宣告的全球來源。如果寶石不存在於此來源,則不會安裝它。

Bundler 會先在為父項選擇的來源中尋找此寶石的子依賴項,但如果在那裡找不到,它會退回全球來源。

注意 Bundler 1.13 中已棄用的功能行為:以這種方式選擇特定來源存放庫也會抑制 GLOBAL SOURCE 中上面所述的模稜兩可的寶石警告。

針對個別寶石使用 :source 選項也會讓該來源可用,作為未指定明確來源的其他任何寶石的可能全球來源。因此,在新增具有明確來源的寶石時,建議您也確保 Gemfile 中的所有其他寶石都使用明確來源。

Git

如有必要,您可以使用 :git 參數指定寶石位於特定 Git 存放庫中。可以透過多種協定存取存放庫

HTTP(S)
gem "rails", git: "https://github.com/rails/rails.git"
SSH
gem "rails", git: "git@github.com:rails/rails.git"
git
gem "rails", git: "git://github.com/rails/rails.git"

如果使用 SSH,您用來執行 bundle install 的使用者必須在他們的 $HOME/.ssh 中擁有適當的可用金鑰。

注意:如果可能,應避免使用 http://git:// URL。這些協定未經驗證,因此中間人攻擊者可以傳遞惡意程式碼並危害您的系統。強烈建議使用 HTTPS 和 SSH。

groupplatformsrequire 選項可用,且行為與一般寶石完全相同。

Git 存放庫在包含寶石的目錄根目錄中至少有一個檔案,副檔名為 .gemspec。此檔案必須包含有效的寶石規格,如同 gem build 指令所預期。

如果 Git 存放庫沒有 .gemspec,Bundler 會嘗試建立一個,但它不會包含任何依賴項、可執行檔或 C 延伸元編譯指令。因此,它可能無法適當地整合到您的應用程式中。

如果 Git 存放庫確實有您附加寶石的 .gemspec,如果提供版本規格,表示只有當 .gemspec 指定與版本規格相符的版本時,Git 存放庫才有效。如果不是,Bundler 會印出警告。

gem "rails", "2.3.8", git: "https://github.com/rails/rails.git"
# bundle install will fail, because the .gemspec in the rails
# repository's master branch specifies version 3.0.0

如果 Git 存放庫沒有您附加寶石的 .gemspec必須提供版本規格。Bundler 會在它建立的簡單 .gemspec 中使用此版本。

Git 儲存庫支援許多其他選項。

branchtagref
必須僅指定其中一個選項。預設為 branch: "master"。例如

gem "rails", git: "https://github.com/rails/rails.git", branch: "5-0-stable"

gem "rails", git: "https://github.com/rails/rails.git", tag: "v5.0.0"

gem "rails", git: "https://github.com/rails/rails.git", ref: "4aded"

子模組
供參考,git 子模組讓您在儲存庫的子資料夾中擁有另一個 git 儲存庫。指定 submodules: true 以讓 bundler 展開 git 儲存庫中包含的任何子模組

如果 git 儲存庫包含多個 .gemspecs,每個 .gemspec 都代表位於檔案系統中與 .gemspec 相同位置的 gem。

|~rails                   [git root]
| |-rails.gemspec         [rails gem located here]
|~actionpack
| |-actionpack.gemspec    [actionpack gem located here]
|~activesupport
| |-activesupport.gemspec [activesupport gem located here]
|...

要安裝位於 git 儲存庫中的 gem,bundler 會變更為包含 gemspec 的目錄,執行 gem build name.gemspec,然後安裝產生的 gem。gem build 指令為 Rubygems 的標準指令,會在 gemspec 所在目錄的環境中評估 .gemspec

Git 來源

可透過 git_source 方法定義自訂 git 來源。提供來源名稱作為引數,以及接收單一引數並將其內插為字串以傳回完整儲存庫位址的區塊

git_source(:stash){ |repo_name| "https://stash.corp.acme.pl/#{repo_name}.git" }
gem 'rails', stash: 'forks/rails'

此外,如果您想選擇特定分支

gem "rails", stash: "forks/rails", branch: "branch_name"

Github

注意:應避免使用此簡寫,直到 Bundler 2.0,因為它目前會擴充為不安全的 git:// URL。這會讓中間人攻擊者危害您的系統。

如果您要使用的 git 儲存庫是公開且由 GitHub 託管,您可以使用 :github 簡寫指定 github 使用者名稱和儲存庫名稱(不含尾端的 ".git"),並以斜線分隔。如果使用者名稱和儲存庫名稱相同,您可以省略其中一個。

gem "rails", github: "rails/rails"
gem "rails", github: "rails"

兩個都等同於

gem "rails", git: "https://github.com/rails/rails.git"

由於 github 方法是 git_source 的專門化,因此它接受 :branch 命名引數。

您也可以直接傳遞拉取要求 URL

gem "rails", github: "https://github.com/rails/rails/pull/43753"

等同於

gem "rails", github: "rails/rails", branch: "refs/pull/43753/head"

Gist

如果您要使用的 git 儲存庫是公開且由 GitHub Gist 託管,您可以使用 :gist 簡寫指定 gist 識別碼(不含尾端的 ".git")。

gem "the_hatch", gist: "4815162342"

等同於

gem "the_hatch", git: "https://gist.github.com/4815162342.git"

由於 gist 方法是 git_source 的專門化,因此它接受 :branch 命名引數。

Bitbucket

如果您要使用的 git 儲存庫是由 Bitbucket 託管且為公開的,您可以使用 :bitbucket 簡寫來指定 bitbucket 使用者名稱和儲存庫名稱(不含尾端的「.git」),並以斜線分隔。如果使用者名稱和儲存庫名稱相同,您可以省略其中一個。

gem "rails", bitbucket: "rails/rails"
gem "rails", bitbucket: "rails"

兩個都等同於

gem "rails", git: "https://rails@bitbucket.org/rails/rails.git"

由於 bitbucket 方法是 git_source 的特殊化,它接受一個名為 :branch 的命名參數。

路徑

您可以指定一個 gem 位於檔案系統上的特定位置。相對路徑是相對於包含 Gemfile 的目錄解析的。

:git 選項的語意類似,:path 選項要求相關目錄包含 gem 的 .gemspec,或者您指定 bundler 應使用的明確版本。

:git 不同,bundler 不會編譯指定為路徑的 gem 的 C 延伸模組。

gem "rails", path: "vendor/rails"

如果您想直接從檔案系統使用多個本機 gem,您可以將全域 path 選項設定為包含 gem 檔案的路徑。這將自動從子目錄載入 gemspec 檔案。

path 'components' do
  gem 'admin_ui'
  gem 'public_ui'
end

來源、Git、路徑、群組和平台的區塊形式

:source:git:path:group:platforms 選項可透過使用區塊形式套用至一組 gem。

source "https://gems.example.com" do
  gem "some_internal_gem"
  gem "another_internal_gem"
end

git "https://github.com/rails/rails.git" do
  gem "activesupport"
  gem "actionpack"
end

platforms :ruby do
  gem "ruby-debug"
  gem "sqlite3"
end

group :development, optional: true do
  gem "wirble"
  gem "faker"
end

在群組區塊形式的情況下,可以提供 :optional 選項,以防止在未列於給予 bundle install 命令的 --with 選項中時,安裝群組。

git 區塊形式的情況下,:ref:branch:tag:submodules 選項可傳遞至 git 方法,且區塊中的所有 gem 都會繼承這些選項。

Gemfile 中存在 source 區塊也會讓該來源可用為任何未指定明確來源的其他 gem 的可能的全域來源。因此,在定義來源區塊時,建議您也確保 Gemfile 中的所有其他 gem 都使用明確來源,無論是透過來源區塊或個別 gem 上的 :source 指令。

Install_if

install_if 方法允許根據 proc 或 lambda 安裝寶石。這對於只有在安裝特定軟體或符合某些其他條件時才能使用的選用寶石特別有用。

install_if -> { RUBY_PLATFORM =~ /darwin/ } do
  gem "pasteboard"
end

Gemspec

.gemspec 檔案是您提供寶石元資料給 Rubygems 的地方。某些必要的 Gemspec 屬性包括寶石的名稱、說明和首頁。您也可以在此指定寶石執行所需的相依性。

如果您希望使用 Bundler 在開發寶石時協助安裝相依性,請使用 gemspec 方法來拉入 .gemspec 檔案中列出的相依性。

gemspec 方法會將任何執行時間相依性新增為預設群組中的寶石需求。它也會將開發相依性新增為 development 群組中的寶石需求。最後,它會新增一個針對專案的寶石需求 (path: '.')。與 Bundler.setup 結合使用時,這允許您在測試程式碼中需要專案檔案,就像專案安裝為寶石一樣;您不需要手動調整載入路徑或透過相對路徑需要專案檔案。

gemspec 方法支援選用的 :path:glob:name:development_group 選項,這些選項控制 bundler 在何處尋找 .gemspec、用於尋找 gemspec 的 glob (預設為:{,*,*/*}.gemspec)、使用的命名 .gemspec (如果存在多個) 以及包含開發相依性的群組。

gemspec 相依性在解析期間遇到版本衝突時,永遠會選取開發中的本機版本,即使有更符合 gemspec 寶石其他需求的遠端版本。

來源優先順序

在嘗試尋找寶石以滿足寶石需求時,bundler 使用下列優先順序

  1. 明確附加到寶石的來源 (使用 :source:path:git)
  2. 對於隱含寶石 (明確寶石的相依性),父項上宣告的任何來源、git 或路徑儲存庫。這會導致 bundler 優先使用 Rails git 儲存庫中的 ActiveSupport 寶石,而不是來自 rubygems.org 的寶石
  3. 如果上述條件都不符合,將會使用全域來源。如果指定多個全域來源,它們會從最後一個優先到第一個,但這已在 Bundler 1.13 中棄用,因此 Bundler 會印出警告,並會在未來中斷並傳回錯誤。
如果您發現錯誤或遺漏,請在 GitHub 上編輯此文件