Bazel 的 Lockfile 功能可記錄專案所需的特定版本或依附元件。透過儲存模組解析度和擴充功能評估的結果,達成了這個目標。Lockfile 會推廣可重現的建構作業,確保開發環境的一致性。此外,當專案依附元件沒有變更時,這項功能可讓 Bazel 略過解析程序,進而提升建構效率。此外, Lockfile 可防止外部程式庫發生非預期的更新或破壞性變更,藉此提高穩定性,進而降低引入錯誤的風險。
產生鎖定檔案
這個 Lockfile 會在工作區根目錄下產生,名為 MODULE.bazel.lock
。它會在建構程序中建立或更新,特別是在模組解析和擴充功能評估之後。Lockfile 會擷取專案目前的狀態,包括 MODULE 檔案、標記、覆寫和其他相關資訊。重要的是,它只會納入目前建構作業呼叫中包含的依附元件。
當影響其依附元件的專案發生變更時, Lockfile 會自動更新以反映新的狀態。如此可確保鎖定檔案能專注於目前建構所需的特定依附元件組合,準確呈現專案解析的依附元件。
鎖定檔案使用方式
鎖定檔案可透過標記 --lockfile_mode
進行控制,在專案狀態與鎖定檔案不同時,可自訂 Bazel 的行為。可用的模式如下:
update
(預設):如果專案狀態與 Lockfile 相符,系統會立即從 Lockfile 傳回解析度結果。否則,系統會執行解析度,並更新鎖定檔案,反映目前的狀態。error
:如果專案狀態與 Lockfile 相符,則系統會從 Lockfile 傳回解析度結果。否則,Bazel 會擲回錯誤,指出專案和鎖定檔案之間的差異。如要確保專案的依附元件保持不變,並將任何差異視為錯誤,這個模式就特別實用。off
:完全未檢查鎖定檔案。
鎖定檔案的優點
Lockfile 提供多項優點,且可多種運用方式:
可重現的版本。透過擷取軟體程式庫的特定版本或依附元件,鎖定檔案可確保建構作業可在不同環境和一段時間後重現。開發人員在建構專案時,可以依賴一致且可預測的結果。
有效跳過解析度。如果自上次建構以來,專案依附元件並未發生變更,鎖定檔案可讓 Bazel 略過解析程序。這可大幅提升建構效率,特別是在解析度可能耗時的情況下。
穩定性和風險降低。鎖定檔案可防止外部程式庫發生意外更新或破壞性變更,進而維持穩定性。將依附元件鎖定於特定版本後,就能降低因不相容或未經測試的更新而引入錯誤的風險。
鎖定檔案內容
Lockfile 包含判斷專案狀態是否變更的所有必要資訊。並包含在目前狀態下建構專案的結果。Lockfile 包含兩個主要部分:
- 模組解析度的輸入內容 (例如
moduleFileHash
、flags
和localOverrideHashes
),以及解析度的輸出內容 (moduleDepGraph
)。 - 對於每個模組擴充功能,鎖定檔案都會納入影響該擴充功能的輸入內容 (以
transitiveDigest
表示),以及執行該擴充功能的輸出內容 (稱為generatedRepoSpecs
)。
以下範例呈現了 Lockfile 的結構,以及各區段的說明:
{
"lockFileVersion": 1,
"moduleFileHash": "b0f47b98a67ee15f9.......8dff8721c66b721e370",
"flags": {
"cmdRegistries": [
"https://bcr.bazel.build/"
],
"cmdModuleOverrides": {},
"allowedYankedVersions": [],
"envVarAllowedYankedVersions": "",
"ignoreDevDependency": false,
"directDependenciesMode": "WARNING",
"compatibilityMode": "ERROR"
},
"localOverrideHashes": {
"bazel_tools": "b5ae1fa37632140aff8.......15c6fe84a1231d6af9"
},
"moduleDepGraph": {
"<root>": {
"name": "",
"version": "",
"executionPlatformsToRegister": [],
"toolchainsToRegister": [],
"extensionUsages": [
{
"extensionBzlFile": "extension.bzl",
"extensionName": "lockfile_ext"
}
],
...
}
},
"moduleExtensions": {
"//:extension.bzl%lockfile_ext": {
"transitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
"generatedRepoSpecs": {
"hello": {
"bzlFile": "@@//:extension.bzl",
...
}
}
}
}
}
模組檔案雜湊
moduleFileHash
代表 MODULE.bazel
檔案內容的雜湊。如果這個檔案發生任何變更,雜湊值會有所不同。
旗幟
Flags
物件會儲存會影響解析度結果的所有旗標。
本機覆寫雜湊
如果根模組包含 local_path_overrides
,這個區段會在本機存放區中儲存 MODULE.bazel
檔案的雜湊。可追蹤此依附元件的變更。
模組依附元件圖
moduleDepGraph
代表使用上述輸入內容的解析程序結果。它構成了執行專案所需的所有模組的依附元件圖。
模組擴充功能
moduleExtensions
區段是一個地圖,只包含目前叫用或先前叫用所用的擴充功能,並排除不再使用的擴充功能。換句話說,如果依附元件圖表中不再使用某個擴充功能,就會從 moduleExtensions
地圖中移除。
此對應表中的每個項目都對應至已使用的擴充功能,並以包含的檔案和名稱做為識別。每個項目的對應值都包含與該擴充功能相關聯的相關資訊:
transitiveDigest
擴充功能實作項目及其遞移 .bzl 檔案的摘要。generatedRepoSpecs
是使用目前輸入內容執行該擴充功能的結果。
用法也是影響擴充功能結果的另一個因素。雖然未儲存在 Lockfile 中,但在比較擴充功能與鎖定檔案中的目前狀態時,會考慮使用權限。
最佳做法
如要充分發揮鎖定檔案功能的優點,請考慮採用下列最佳做法:
請定期更新鎖定檔案,反映專案依附元件或設定的變更。這可確保後續建構是以最新且準確的依附元件組合為基礎。
將 Lockfile 納入版本管控,以利協同合作,並確保所有團隊成員都能存取相同的 Lockfile,促進專案中一致的開發環境。
只要按照這些最佳做法,您就可以有效利用 Bazel 中的 Lockfile 功能,創造更有效率、更穩定、協同運作的軟體開發工作流程。