包依賴
依賴是 pub 包管理器的核心概念之一。依賴項是您的包正常工作所需的另一個包。依賴項在您的 pubspec 中指定。您只列出直接依賴項:您的包直接使用的軟體。Pub 會為您處理傳遞依賴項。
本頁面詳細介紹瞭如何指定依賴項。最後列出了包依賴項的最佳實踐。
概覽
#對於每個依賴項,您需要指定所依賴包的名稱以及允許的該包的版本範圍。您還可以指定源。源告訴 pub 如何定位包。
例如,您可以按以下格式指定依賴項
dependencies:
transmogrify: ^1.0.0此 YAML 程式碼建立了對 transmogrify 包的依賴,使用預設包倉庫 (pub.dev),並允許從 1.0.0 到 2.0.0(但不包括 2.0.0)的任何版本。要了解此語法,請檢視版本約束。
要指定除 pub.dev 之外的源,請使用 sdk、hosted、git 或 path。例如,以下 YAML 程式碼使用 path 來告訴 pub 從本地目錄獲取 transmogrify
dependencies:
transmogrify:
path: /Users/me/transmogrify下一節將介紹每個依賴項源的格式。
依賴來源
#Pub 可以使用以下源來定位包
託管包
#託管包是可以從 pub.dev 網站(或支援相同 API 的其他 HTTP 伺服器)下載的包。以下是宣告對託管包依賴的示例:
dependencies:
transmogrify: ^1.4.0此示例指定您的包依賴於名為 transmogrify 的託管包,並且支援從 1.4.0 到 2.0.0(但不包括 2.0.0 本身)的任何版本。
如果您想使用自己的包倉庫,可以使用 hosted 來指定其 URL。以下 YAML 程式碼使用 hosted 源建立了對 transmogrify 包的依賴:
environment:
sdk: '^2.19.0'
dependencies:
transmogrify:
hosted: https://some-package-server.com
version: ^1.4.0版本約束是可選的,但建議使用。如果未指定版本約束,則預設為 any。
Git 包
#有時您走在技術前沿,需要使用尚未正式釋出的包。也許您的包本身仍在開發中,並且正在同時使用其他正在開發的包。為了簡化此過程,您可以直接依賴儲存在 Git 倉庫中的包。
dependencies:
kittens:
git: https://github.com/munificent/kittens.git這裡的 git 表示此包是使用 Git 找到的,其後的 URL 是可用於克隆此包的 Git URL。
即使包倉庫是私有的,您也可以配置 git 以使用HTTPS 訪問金鑰或SSH 金鑰對訪問倉庫。然後,您可以使用倉庫對應的 URL 依賴該包:
dependencies:
kittens:
# SSH URL:
git: git@github.com:munificent/kittens.gitdart pub 命令會呼叫 git clone 作為子程序,因此您只需提供一個在執行 git clone <url> 時能夠正常工作的 <url>。
如果您想依賴特定的提交、分支或標籤,請在描述中新增一個 ref 鍵:
dependencies:
kittens:
git:
url: git@github.com:munificent/kittens.git
ref: some-branchref 可以是 Git 允許識別提交的任何內容。
Pub 假設包位於 Git 倉庫的根目錄。要指定倉庫中的不同位置,請指定相對於倉庫根目錄的 path:
dependencies:
kittens:
git:
url: git@github.com:munificent/cats.git
path: path/to/kittens該路徑是相對於 Git 倉庫根目錄的。
上傳到 pub.dev 的包不允許使用 Git 依賴。
路徑包
#有時您會同時處理多個相關包。也許您正在構建一個框架,同時也在開發一個使用該框架的應用程式。在這些情況下,在開發期間,您會希望依賴本地檔案系統上該包的即時版本。這樣,一個包中的更改會立即被依賴它的包檢測到。
為了處理這種情況,pub 支援路徑依賴。
dependencies:
transmogrify:
path: /Users/me/transmogrify這表示 transmogrify 的根目錄是 /Users/me/transmogrify。對於此依賴項,pub 會直接為引用包目錄的 lib 目錄生成一個符號連結。您對依賴包所做的任何更改都會立即生效。您無需每次更改依賴包時都執行 pub。
允許使用相對路徑,並將其視為相對於包含您的 pubspec 檔案的目錄。
路徑依賴對於本地開發很有用,但在與外界共享程式碼時不起作用——並非所有人都能訪問您的檔案系統。因此,如果您的包在 pubspec 中有任何路徑依賴,您就無法將其上傳到 pub.dev 網站。
相反,典型的工作流程是
- 在本地編輯您的 pubspec 以使用路徑依賴。
- 開發主包及其依賴的包。
- 一旦它們都能正常工作,就釋出依賴包。
- 更改您的 pubspec,使其指向現在託管的依賴包版本。
- 如果需要,也釋出您的主包。
SDK
#SDK 源用於隨包一起釋出的任何 SDK,這些 SDK 本身也可能是依賴項。目前,Flutter 是唯一受支援的 SDK。
語法如下所示
dependencies:
flutter_driver:
sdk: fluttersdk: 後面的識別符號表示該包來自哪個 SDK。如果它是 flutter,則只要滿足以下條件,該依賴項就可滿足:
- Pub 在
flutter可執行檔案的上下文中執行 - Flutter SDK 包含具有給定名稱的包
如果它是一個未知識別符號,則該依賴項始終被視為未滿足。
版本約束
#假設您的包 A 依賴於包 B。您如何向其他開發者表明包 B 的哪個版本與包 A 的給定版本相容?
為了讓開發者瞭解版本相容性,請指定版本約束。您希望允許儘可能寬的版本範圍,以提供包使用者靈活性。該範圍應排除不相容或未經測試的版本。
Dart 社群使用語義化版本控制1。
從 Dart 2.19 開始,您可以使用傳統語法或插入符語法來表達版本約束。兩種語法都指定了相容的版本範圍。
傳統語法提供了一個明確的範圍,如 '>=1.2.3 <2.0.0'。插入符語法提供了一個明確的起始版本 ^1.2.3。
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 的版本系統,請參閱包版本控制頁面。
傳統語法
#使用傳統語法的版本約束可以使用以下任何值
| 值 | 允許 | 使用? | 備註 |
|---|---|---|---|
任意 | 所有版本 | 否 | 用作空版本約束的明確宣告。 |
1.2.3 | 僅給定版本 | 否 | 由於對使用您包的應用程式施加了額外限制,因此限制了您包的採用。 |
>=1.2.3 | 給定版本或更高版本 | 是 | |
>1.2.3 | 晚於給定版本的版本 | 否 | |
<=1.2.3 | 給定版本或更早版本 | 否 | |
<1.2.3 | 早於給定版本的版本 | 否 | 當您知道某個上限版本不相容您的包時,請使用此項。此版本可能是引入某些破壞性變更的第一個版本。 |
您可以指定版本值的任意組合,只要它們的範圍有交集。例如,如果您將版本值設定為 '>=1.2.3 <2.0.0',這將結合這兩個限制,因此依賴項可以是 1.2.3 到 2.0.0(不包括 2.0.0 本身)之間的任何版本。
插入符語法
#插入符語法以緊湊的方式表達版本約束。^version 意味著保證與給定版本向後相容的所有版本範圍。此範圍將包括所有版本,直到下一個引入破壞性變更的版本。由於 Dart 使用語義化版本控制,對於任何 1.0 或更高版本的包,這將是下一個主要版本;對於任何早於 1.0 版本的包,這將是下一個次要版本。
| 版本值 | 範圍涵蓋至 | 插入符語法 | 傳統語法 |
|---|---|---|---|
| >=1.0 | 下一個主要版本 | ^1.3.0 | '>=1.3.0 <2.0.0' |
| <1.0 | 下一個次要版本 | ^0.1.2 | '>=0.1.2 <0.2.0' |
以下示例展示了插入符語法
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 會類似這樣:
dev_dependencies:
test: ^1.25.0Pub 會獲取您的包所依賴的每個包,以及這些包所傳遞依賴的所有內容。它還會獲取您包的開發依賴,但會忽略任何被依賴包的開發依賴。Pub 只獲取您自己包的開發依賴。因此,當您的包依賴 transmogrify 時,它將獲取 transmogrify 但不獲取 test。
決定使用常規依賴還是開發依賴的規則很簡單:如果依賴項是從您的 lib 或 bin 目錄中的內容匯入的,則它需要是一個常規依賴。如果它只從 test、example 等目錄匯入,則它可以而且應該是一個開發依賴。
使用開發依賴可以使依賴圖更小。這使得 pub 執行更快,並且更容易找到滿足所有約束的包版本集。
依賴覆蓋
#您可以使用 dependency_overrides 來暫時覆蓋所有對依賴項的引用。
例如,您可能正在更新已釋出的包 transmogrify 的本地副本。Transmogrify 在您的依賴圖中被其他包使用,但您不想在本地克隆每個包並更改每個 pubspec 以測試您本地的 transmogrify 副本。
在這種情況下,您可以使用 dependency_overrides 來覆蓋依賴項,指定包含包本地副本的目錄。
pubspec 檔案看起來會像下面這樣
name: my_app
dependencies:
transmogrify: ^1.2.0
dependency_overrides:
transmogrify:
path: ../transmogrify_patch/當您執行 dart pub get 或 dart pub upgrade 時,pubspec 的 lockfile 會更新以反映您依賴項的新路徑,並且無論何處使用 transmogrify,pub 都會使用本地版本。
您還可以使用 dependency_overrides 來指定包的特定版本:
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.yaml 旁邊放置一個名為 pubspec_overrides.yaml 的檔案。
該檔案中的屬性將覆蓋 pubspec.yaml 中的屬性。
可以覆蓋的屬性有
dependency_overridesworkspaceresolution
這有助於避免意外將臨時覆蓋提交到版本控制。它還可以更輕鬆地從指令碼生成覆蓋。
在 pub 工作區中,每個工作區包都可以有一個 pubspec_overrides.yaml 檔案。
最佳實踐
#積極主動地管理您的依賴項。儘可能確保您的包依賴於最新版本的包。如果您的包依賴於一個過時的包,那麼該過時的包可能又依賴其依賴樹中的其他過時包。過時的包版本可能對應用程式的穩定性、效能和質量產生負面影響。
我們建議以下包依賴最佳實踐。
使用插入符語法
#使用插入符語法指定依賴項。這允許 pub 工具在包的新版本可用時選擇它們。此外,它還對允許的版本設定了上限。
依賴最新的穩定包版本
#使用 dart pub upgrade 更新到 pubspec 允許的最新包版本。要識別您的應用或包中未處於最新穩定版本的依賴項,請使用 dart pub outdated。
收緊開發依賴的版本約束
#開發依賴定義了您僅在開發時才需要的包。完成的應用程式不需要這些包。這些包的示例包括測試或程式碼生成工具。將 dev_dependencies 中包的版本約束設定為您的包所依賴的最新版本的下限。
收緊開發依賴的版本約束可能類似於以下內容
dev_dependencies:
build_runner: ^2.4.15
lints: ^5.1.1
test: ^1.25.15此 YAML 將 dev_dependencies 設定為最新的補丁版本。
更新包依賴時進行測試
#如果您執行 dart pub upgrade 而不更新您的 pubspec,API 應該保持不變,並且您的程式碼應該像以前一樣執行——但請務必測試以確保。如果您修改 pubspec 並更新到新的主要版本,那麼您可能會遇到破壞性變更,因此需要更徹底地測試。
使用降級依賴進行測試
#在開發用於釋出的包時,通常最好允許儘可能廣泛的依賴約束。廣泛的依賴約束減少了包使用者面臨版本解析衝突的可能性。
例如,如果您依賴 foo: ^1.2.3 並且釋出了 foo 的 1.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 選項以確保提取的包內容與原始存檔的內容匹配。在不修改 lockfile 的情況下,此標誌僅在以下情況下解析新依賴項:
pubspec.yaml滿足要求pubspec.lock不缺失- 包的內容雜湊匹配