跳到主要內容

套件相依性

相依性是 pub 套件管理器的核心概念之一。相依性是您的套件運作所需的另一個套件。相依性在您的 pubspec 中指定。您僅列出直接相依性:您的套件直接使用的軟體。Pub 會為您處理遞移相依性

本頁面詳細說明如何指定相依性。結尾列出套件相依性的最佳實務

總覽

#

針對每個相依性,您需要指定您相依的套件名稱,以及您允許的該套件版本範圍。您也可以指定來源。「來源」會告知 pub 如何找到套件。

例如,您可以使用以下格式指定相依性

yaml
dependencies:
  transmogrify: ^1.0.0

此 YAML 程式碼建立對 transmogrify 套件的相依性,使用預設套件儲存庫 (pub.dev) 並允許從 1.0.02.0.0 (但不包含 2.0.0) 的任何版本。若要瞭解此語法,請查看版本約束

若要指定 pub.dev 以外的來源,請使用 sdkhostedgitpath。例如,以下 YAML 程式碼使用 path 告知 pub 從本機目錄取得 transmogrify

yaml
dependencies:
  transmogrify:
    path: /Users/me/transmogrify

下一節說明每個相依性來源的格式。

相依性來源

#

Pub 可以使用下列來源來尋找套件

託管套件

#

託管套件是可以從 pub.dev 網站 (或其他使用相同 API 的 HTTP 伺服器) 下載的套件。以下範例說明如何宣告對託管套件的相依性

yaml
dependencies:
  transmogrify: ^1.4.0

此範例指定您的套件相依於名為 transmogrify 的託管套件,且適用於從 1.4.0 到 2.0.0 (但不包含 2.0.0 本身) 的任何版本。

如果您想要使用您自己的套件儲存庫,可以使用 hosted 指定其 URL。以下 YAML 程式碼建立對 transmogrify 套件的相依性,使用 hosted 來源

yaml
environment:
  sdk: '^2.19.0'

dependencies:
  transmogrify:
    hosted: https://some-package-server.com
    version: ^1.4.0

版本約束是選用的,但建議使用。如果未提供版本約束,則會假設為 any

Git 套件

#

有時您會走在尖端,需要使用尚未正式發佈的套件。也許您的套件本身仍在開發中,並且正在使用同時開發的其他套件。為了讓此過程更輕鬆,您可以直接依賴儲存在 Git 儲存庫中的套件。

yaml
dependencies:
  kittens:
    git: https://github.com/munificent/kittens.git

此處的 git 表示此套件是使用 Git 找到的,之後的 URL 是可用於複製套件的 Git URL。

即使套件儲存庫是私有的,您也可以設定您的 git 設定,以使用HTTPS 存取金鑰SSH 金鑰組存取儲存庫。然後,您可以使用儲存庫的對應 URL 來依賴套件

yaml
dependencies:
  kittens:
    # SSH URL:
    git: git@github.com:munificent/kittens.git

dart pub 命令會呼叫 git clone 作為子程序,因此您只需要提供在執行 git clone <url> 時有效的 <url> 即可。

如果您想要依賴特定的提交、分支或標籤,請將 ref 金鑰新增至描述

yaml
dependencies:
  kittens:
    git:
      url: git@github.com:munificent/kittens.git
      ref: some-branch

ref 可以是 Git 允許識別提交的任何項目。

Pub 假設套件位於 Git 儲存庫的根目錄中。若要指定儲存庫中的不同位置,請指定相對於儲存庫根目錄的 path

yaml
dependencies:
  kittens:
    git:
      url: git@github.com:munificent/cats.git
      path: path/to/kittens

路徑是相對於 Git 儲存庫的根目錄。

Git 相依性不允許作為上傳到 pub.dev 的套件的相依性。

路徑套件

#

有時您會發現自己同時處理多個相關套件。也許您正在建立框架,同時建置使用該框架的應用程式。在這些情況下,在開發期間,您真的想要依賴本機檔案系統上該套件的即時版本。這樣,一個套件中的變更會立即被依賴它的套件擷取。

為了處理這種情況,pub 支援路徑相依性

yaml
dependencies:
  transmogrify:
    path: /Users/me/transmogrify

這表示 transmogrify 的根目錄是 /Users/me/transmogrify。對於此相依性,pub 會直接為參照套件目錄的 lib 目錄產生符號連結。您對相依套件所做的任何變更都會立即生效。您不需要每次變更相依套件時都執行 pub。

允許使用相對路徑,並且會將其視為相對於包含您的 pubspec 的目錄。

路徑相依性對於本機開發很有用,但在與外界共享程式碼時不起作用 — 並非所有人都能存取您的檔案系統。因此,如果套件的 pubspec 中有任何路徑相依性,您就無法將該套件上傳到 pub.dev 網站

相反地,典型的工作流程是

  1. 在本機編輯您的 pubspec 以使用路徑相依性。
  2. 處理主要套件及其相依的套件。
  3. 一旦兩者都運作正常,請發佈相依的套件。
  4. 變更您的 pubspec 以指向其相依項的現在託管版本。
  5. 如果您願意,也可以發佈您的主要套件。

SDK

#

SDK 來源用於隨套件一起提供的任何 SDK,這些 SDK 本身可能是相依性。目前,僅支援 Flutter SDK。

語法如下所示

yaml
dependencies:
  flutter_driver:
    sdk: flutter

sdk: 後面的識別碼表示套件來自哪個 SDK。如果是 flutter,則只要滿足以下條件,相依性即可滿足

  • Pub 在 flutter 可執行檔的內容中執行
  • Flutter SDK 包含具有指定名稱的套件

如果是未知的識別碼,則始終認為相依性不滿足。

版本約束

#

假設您的套件 A 依賴於套件 B。您如何告知其他開發人員哪個版本的套件 B 與給定版本的套件 A 保持相容?

為了讓開發人員瞭解版本相容性,請指定版本約束。您想要允許盡可能廣泛的版本範圍,以為您的套件使用者提供彈性。範圍應排除無法運作或尚未經過測試的版本。

Dart 社群使用語意化版本控制1

從 Dart 2.19 開始,您可以使用傳統語法Caret 語法來表達版本約束。兩種語法都指定相容版本的範圍。

傳統語法提供明確的範圍,例如 '>=1.2.3 <2.0.0'。Caret 語法提供明確的起始版本 ^1.2.3

yaml
environment:
  # This package must use a 3.x version of the Dart SDK starting with 3.2.
  sdk: ^3.2.0

dependencies:
  transmogrify:
    hosted:
      name: transmogrify
      url: https://some-package-server.com
    # This package must use a 1.x version of transmogrify starting with 1.4.
    version: ^1.4.0

若要深入瞭解 pub 的版本系統,請參閱套件版本控制頁面

傳統語法

#

使用傳統語法的版本約束可以使用下列任何值

允許使用?注意事項
any所有版本作為空版本約束的明確宣告。
1.2.3僅給定版本由於對使用您套件的應用程式施加了額外限制,因此限制了您套件的採用。
>=1.2.3給定版本或更新版本
>1.2.3晚於給定版本的版本
<=1.2.3給定版本或更早版本
<1.2.3早於給定版本的版本當您知道與您的套件相容的上限版本時,請使用此版本。此版本可能是第一個引入某些破壞性變更的版本。

您可以指定版本值的任何組合,因為它們的範圍會相交。例如,如果您將版本值設定為 '>=1.2.3 <2.0.0',這會結合兩個限制,因此相依性可以是從 1.2.32.0.0 (不包含 2.0.0 本身) 的任何版本。

Caret 語法

#

Caret 語法以精簡的方式表達版本約束。^version 表示保證與給定版本向後相容的所有版本的範圍。此範圍將包含所有版本,直到下一個引入破壞性變更的版本。由於 Dart 使用語意化版本控制,因此對於任何 1.0 或更高版本的套件版本,這將是下一個主要版本,或者對於任何早於 1.0 的套件版本,這將是下一個次要版本。

版本值範圍涵蓋至Caret 語法傳統語法
>=1.0下一個主要版本^1.3.0'>=1.3.0 <2.0.0'
<1.0下一個次要版本^0.1.2'>=0.1.2 <0.2.0'

以下範例顯示 Caret 語法

yaml
dependencies:
  # Covers all versions from 1.3.0 to 1.y.z, not including 2.0.0
  path: ^1.3.0
  # Covers all versions from 1.1.0 to 1.y.z, not including 2.0.0
  collection: ^1.1.0
  # Covers all versions from 0.1.2 to 0.1.z, not including 0.2.0
  string_scanner: ^0.1.2

開發相依性

#

Pub 支援兩種相依性類型:一般相依性和開發相依性。開發相依性與一般相依性的不同之處在於您所相依套件的開發相依性會被忽略。以下範例

假設 transmogrify 套件在其測試中 (且僅在其測試中) 使用 test 套件。如果有人只想使用 transmogrify — 匯入其程式庫 — 則實際上不需要 test。在這種情況下,它將 test 指定為開發相依性。其 pubspec 將包含類似於

yaml
dev_dependencies:
  test: ^1.25.0

Pub 會取得您的套件所相依的每個套件,以及這些套件所相依的所有項目 (以遞移方式)。它也會取得您套件的開發相依性,但會忽略任何相依套件的開發相依性。Pub 僅取得套件的開發相依性。因此,當您的套件相依於 transmogrify 時,它將取得 transmogrify,但不會取得 test

決定一般相依性或開發相依性的規則很簡單:如果相依性是從您的 libbin 目錄中的某個項目匯入的,則它需要是一般相依性。如果僅從 testexample 等匯入,則它可以而且應該是開發相依性。

使用開發相依性可使相依性圖表更小。這可以使 pub 執行速度更快,並更容易找到一組滿足所有約束的套件版本。

相依性覆寫

#

您可以使用 dependency_overrides 暫時覆寫對相依性的所有參照。

例如,也許您正在更新已發佈套件 transmogrify 的本機副本。Transmogrify 由相依性圖表中的其他套件使用,但您不想在本機複製每個套件並變更每個 pubspec 以測試 transmogrify 的本機副本。

在這種情況下,您可以使用 dependency_overrides 覆寫相依性,以指定包含套件本機副本的目錄。

pubspec 看起來會像以下內容

yaml
name: my_app
dependencies:
  transmogrify: ^1.2.0
dependency_overrides:
  transmogrify:
    path: ../transmogrify_patch/

當您執行 dart pub getdart pub upgrade 時,pubspec 的鎖定檔會更新以反映相依性的新路徑,並且在任何使用 transmogrify 的地方,pub 都會改為使用本機版本。

您也可以使用 dependency_overrides 指定套件的特定版本

yaml
name: my_app
dependencies:
  transmogrify: ^1.2.0
dependency_overrides:
  transmogrify: '3.2.1'

在套件解析期間,僅考慮套件自身 pubspec 中的相依性覆寫。任何相依套件內部的相依性覆寫都會被忽略。

因此,如果您將套件發佈到 pub.dev,請記住,您的套件的相依性覆寫會被您套件的所有使用者忽略。

如果您正在使用 pub 工作區,則可以在每個工作區套件中都有 dependency_overrides,但單一套件在工作區中只能覆寫一次。

pubspec_overrides.yaml

#

如果您想要變更 pubspec.yaml 檔案解析的某些方面,但不想要變更實際檔案,則可以將名為 pubspec_overrides.yaml 的檔案放在 pubspec.yaml 旁邊。

該檔案中的屬性將覆寫 pubspec.yaml 中的屬性。

可以覆寫的屬性為

  • dependency_overrides
  • workspace
  • resolution

這對於避免意外地將臨時覆寫檢查到版本控制中可能很有用。它也可以更輕鬆地從指令碼產生覆寫。

pub 工作區中,每個工作區套件都可以有一個 pubspec_overrides.yaml 檔案。

最佳實務

#

主動管理您的相依性。請確保您的套件在可能的情況下依賴最新版本的套件。如果您的套件依賴於過時的套件,則該過時的套件可能會在其相依性樹狀結構中依賴其他過時的套件。過時版本的套件可能會對應用程式的穩定性、效能和品質產生負面影響。

我們建議以下套件相依性的最佳實務。

使用 Caret 語法

#

使用 Caret 語法指定相依性。這允許 pub 工具在較新版本可用時選取較新版本。此外,它還對允許的版本設定了上限。

依賴最新的穩定套件版本

#

使用 dart pub upgrade 更新到您的 pubspec 允許的最新套件版本。若要識別您的應用程式或套件中不是最新穩定版本的相依性,請使用 dart pub outdated

強化開發相依性的版本約束

#

開發相依性定義了您僅在開發時才需要的套件。已完成的應用程式將不需要這些套件。這些套件的範例包括測試或程式碼產生工具。在 dev_dependencies 中設定套件的版本約束,使其下限為您的套件所依賴的最新版本。

強化您的開發相依性的版本約束可能類似於以下內容

yaml
dev_dependencies:
  build_runner: ^2.4.13
  lints: ^2.1.1
  test: ^1.25.8

此 YAML 將 dev_dependencies 設定為最新的修補程式版本。

每當您更新套件相依性時進行測試

#

如果您在不更新 pubspec 的情況下執行 dart pub upgrade,API 應保持不變,並且您的程式碼應照常執行 — 但請進行測試以確保。如果您修改 pubspec 並更新到新的主要版本,則可能會遇到破壞性變更,因此您需要進行更徹底的測試。

使用降級的相依性進行測試

#

在開發要發佈的套件時,通常最好允許盡可能廣泛的相依性約束。廣泛的相依性約束降低了套件使用者面臨版本解析衝突的可能性。

例如,如果您對 foo: ^1.2.3 有相依性,並且發佈了 foo1.3.0 版本,則保留現有的相依性約束 (^1.2.3) 可能很合理。但是,如果您的套件開始使用在 1.3.0 中新增的功能,則您需要將您的約束提升到 ^1.3.0

但是,在必要時很容易忘記提升相依性約束。因此,最佳實務是在發佈之前針對降級的相依性測試您的套件。

若要針對降級的相依性進行測試,請執行 dart pub downgrade 並驗證您的套件仍然可以進行分析而不會出錯,並且通過所有測試

dart pub downgrade
dart analyze
dart test

使用降級的相依性進行測試應與使用最新相依性的正常測試同時進行。如果需要提升相依性約束,請自行變更它們,或使用 dart pub upgrade --tighten 將相依性更新到最新版本。

驗證下載套件的完整性

#

當擷取新的相依性時,請使用 --enforce-lockfile 選項,以確保擷取的套件內容與原始封存的內容相符。在不修改鎖定檔的情況下,此標記僅在以下情況下解析新的相依性

  • pubspec.yaml 滿足
  • pubspec.lock 未遺失
  • 套件的內容雜湊相符