Tính năng lockfile trong Bazel cho phép ghi lại các phiên bản hoặc phần phụ thuộc cụ thể của các thư viện phần mềm hoặc gói mà một dự án yêu cầu. Việc này được thực hiện bằng cách lưu trữ kết quả của quá trình phân giải mô-đun và đánh giá tiện ích. Tệp khoá giúp tạo các bản dựng có thể tái tạo, đảm bảo môi trường phát triển nhất quán. Ngoài ra, tính năng này còn nâng cao hiệu quả của bản dựng bằng cách cho phép Bazel bỏ qua quy trình phân giải khi không có thay đổi nào trong các phần phụ thuộc của dự án. Hơn nữa, tệp khoá giúp cải thiện độ ổn định bằng cách ngăn chặn các bản cập nhật không mong muốn hoặc các thay đổi gây lỗi trong thư viện bên ngoài, từ đó giảm nguy cơ xuất hiện lỗi.
Tạo tệp khoá
Lockfile được tạo trong thư mục gốc của không gian làm việc với tên MODULE.bazel.lock
. Tệp này được tạo hoặc cập nhật trong quá trình xây dựng, cụ thể là sau khi phân giải mô-đun và đánh giá tiện ích. Lockfile ghi lại trạng thái hiện tại của dự án, bao gồm tệp MODULE, cờ, ghi đè và các thông tin liên quan khác. Điều quan trọng là nó chỉ bao gồm các phần phụ thuộc có trong lệnh gọi hiện tại của bản dựng.
Khi có thay đổi trong dự án ảnh hưởng đến các phần phụ thuộc của dự án, lockfile sẽ tự động cập nhật để phản ánh trạng thái mới. Điều này đảm bảo rằng lockfile vẫn tập trung vào một nhóm phần phụ thuộc cụ thể cần thiết cho bản dựng hiện tại, cung cấp thông tin chính xác về các phần phụ thuộc đã phân giải của dự án.
Sử dụng tệp khoá
Bạn có thể kiểm soát lockfile bằng cờ --lockfile_mode
để tuỳ chỉnh hành vi của Bazel khi trạng thái dự án khác với lockfile. Các chế độ hiện có là:
update
(Mặc định): Nếu trạng thái dự án khớp với tệp khoá, thì kết quả phân giải sẽ được trả về ngay lập tức từ tệp khoá. Nếu không, quá trình phân giải sẽ được thực thi và lockfile sẽ được cập nhật để phản ánh trạng thái hiện tại.error
: Nếu trạng thái dự án khớp với tệp khoá, thì kết quả phân giải sẽ được trả về từ tệp khoá. Nếu không, Bazel sẽ báo lỗi cho biết các biến thể giữa dự án và tệp khoá. Chế độ này đặc biệt hữu ích khi bạn muốn đảm bảo rằng các phần phụ thuộc của dự án vẫn không thay đổi và mọi khác biệt đều được coi là lỗi.off
: Lockfile hoàn toàn không được kiểm tra.
Lợi ích của tệp khoá
Tệp khoá mang lại một số lợi ích và có thể được sử dụng theo nhiều cách:
Bản dựng có thể mô phỏng. Bằng cách ghi lại các phiên bản hoặc phần phụ thuộc cụ thể của thư viện phần mềm, tệp khoá đảm bảo rằng các bản dựng có thể tái tạo trên nhiều môi trường và theo thời gian. Nhà phát triển có thể dựa vào kết quả nhất quán và có thể dự đoán được khi tạo dự án.
Bỏ qua độ phân giải một cách hiệu quả. Tệp khoá cho phép Bazel bỏ qua quy trình phân giải nếu không có thay đổi nào trong các phần phụ thuộc của dự án kể từ bản dựng gần đây nhất. Điều này giúp cải thiện đáng kể hiệu suất bản dựng, đặc biệt là trong các trường hợp có thể mất nhiều thời gian để phân giải.
Tính ổn định và giảm rủi ro. Lockfile giúp duy trì tính ổn định bằng cách ngăn chặn các bản cập nhật không mong muốn hoặc các thay đổi gây lỗi trong thư viện bên ngoài. Bằng cách khoá các phần phụ thuộc vào các phiên bản cụ thể, bạn sẽ giảm được nguy cơ xuất hiện lỗi do các bản cập nhật không tương thích hoặc chưa được kiểm thử.
Nội dung của tệp khoá
Tệp khoá chứa tất cả thông tin cần thiết để xác định xem trạng thái dự án có thay đổi hay không. Báo cáo này cũng bao gồm kết quả của việc tạo dự án ở trạng thái hiện tại. Tệp khoá bao gồm hai phần chính:
- Đầu vào của quá trình phân giải mô-đun, chẳng hạn như
moduleFileHash
,flags
vàlocalOverrideHashes
, cũng như đầu ra của quá trình phân giải, đó làmoduleDepGraph
. - Đối với mỗi tiện ích mô-đun, tệp khoá bao gồm các đầu vào ảnh hưởng đến tiện ích đó, được biểu thị bằng
transitiveDigest
và đầu ra của việc chạy tiện ích đó được gọi làgeneratedRepoSpecs
Sau đây là ví dụ minh hoạ cấu trúc của tệp khoá, cùng với nội dung giải thích cho từng phần:
{
"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",
...
}
}
}
}
}
Hàm băm tệp mô-đun
moduleFileHash
biểu thị hàm băm của nội dung tệp MODULE.bazel
. Nếu có bất kỳ thay đổi nào xảy ra trong tệp này, giá trị băm sẽ khác.
Cờ
Đối tượng Flags
lưu trữ tất cả các cờ có thể ảnh hưởng đến kết quả phân giải.
Băm ghi đè cục bộ
Nếu mô-đun gốc có chứa local_path_overrides
, thì phần này sẽ lưu trữ hàm băm của tệp MODULE.bazel
trong kho lưu trữ cục bộ. Thao tác này cho phép theo dõi các thay đổi đối với phần phụ thuộc này.
Biểu đồ phần phụ thuộc của mô-đun
moduleDepGraph
biểu thị kết quả của quy trình phân giải bằng cách sử dụng các đầu vào được đề cập ở trên. Nó tạo thành biểu đồ phần phụ thuộc của tất cả các mô-đun cần thiết để chạy dự án.
Tiện ích mô-đun
Phần moduleExtensions
là một bản đồ chỉ bao gồm các tiện ích được dùng trong lệnh gọi hiện tại hoặc lệnh gọi trước đó, đồng thời loại trừ mọi tiện ích không còn được sử dụng. Nói cách khác, nếu một tiện ích không còn được dùng nữa trong biểu đồ phần phụ thuộc, thì tiện ích đó sẽ bị xoá khỏi bản đồ moduleExtensions
.
Mỗi mục trong bản đồ này tương ứng với một tiện ích đã dùng và được xác định bằng tệp và tên chứa tiện ích đó. Giá trị tương ứng cho mỗi mục chứa thông tin liên quan được liên kết với tiện ích đó:
transitiveDigest
là bản tóm tắt của quá trình triển khai tiện ích và các tệp .bzl bắc cầu của tiện ích đó.generatedRepoSpecs
là kết quả của việc chạy tiện ích đó với dữ liệu đầu vào hiện tại.
Một yếu tố khác có thể ảnh hưởng đến kết quả của phần mở rộng là mức sử dụng. Mặc dù không được lưu trữ trong tệp khoá, nhưng các lượt sử dụng sẽ được xem xét khi so sánh trạng thái hiện tại của tiện ích với trạng thái trong tệp khoá.
Các phương pháp hay nhất
Để tối đa hoá lợi ích của tính năng lockfile, hãy cân nhắc các phương pháp hay nhất sau đây:
Thường xuyên cập nhật tệp khoá để phản ánh những thay đổi trong cấu hình hoặc các phần phụ thuộc của dự án. Điều này đảm bảo rằng các bản dựng tiếp theo dựa trên bộ phần phụ thuộc mới nhất và chính xác nhất.
Đưa tệp khoá vào hệ thống kiểm soát phiên bản để tạo điều kiện cộng tác và đảm bảo rằng tất cả thành viên trong nhóm đều có quyền truy cập vào cùng một tệp khoá, từ đó thúc đẩy môi trường phát triển nhất quán trong toàn dự án.
Bằng cách làm theo các phương pháp hay nhất này, bạn có thể sử dụng hiệu quả tính năng lockfile trong Bazel, nhờ đó có quy trình phát triển phần mềm hiệu quả, đáng tin cậy và mang tính cộng tác hơn.