Tệp Bazel Lockfile

Báo cáo sự cố Xem nguồn

Tính năng tệp khoá 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. Để làm được điều này, kho lưu trữ kết quả đánh giá độ phân giải của mô-đun và tiện ích. Tệp khoá thúc đẩy 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 giúp tăng hiệu quả xây dựng bằng cách cho phép Bazel bỏ qua quy trình giải quyết 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á còn 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 có thể gây lỗi trong thư viện bên ngoài, từ đó giảm nguy cơ gây ra lỗi.

Tạo tệp khoá

Tệp khoá được tạo trong thư mục gốc của không gian làm việc có tên MODULE.bazel.lock. API 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. Tệp khoá ghi lại trạng thái hiện tại của dự án, bao gồm cả tệp MODULE, cờ, nội dung ghi đè và các thông tin liên quan khác. Quan trọng là tệp này 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ác thay đổi xảy ra trong dự án ảnh hưởng đến các phần phụ thuộc của dự án, tệp khoá sẽ tự động được cập nhật để phản ánh trạng thái mới. Điều này đảm bảo rằng tệp khoá vẫn tập trung vào bộ 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 trình bày chính xác về các phần phụ thuộc đã được phân giải của dự án.

Cách sử dụng tệp Lockfile

Bạn có thể kiểm soát tệp khoá (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 tệp khoá. Hiện có các chế độ sau:

  • update (Mặc định): Nếu trạng thái dự án khớp với tệp khoá, kết quả phân giải sẽ ngay lập tức được trả về từ tệp khoá. Nếu không, độ phân giải sẽ được thực thi và tệp khoá 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á, kết quả phân giải sẽ được trả về từ tệp khoá. Nếu không, Bazel sẽ gửi 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 không thay đổi và mọi sự khác biệt đều được coi là lỗi.
  • off: Tệp bị khoá hoàn toàn không được kiểm tra.

Lợi ích của Lockfile

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ể tái tạo. Bằng cách thu thập 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 các kết quả nhất quán và có thể dự đoán khi xây dựng dự án.

  • Bỏ qua độ phân giải hiệu quả. Tệp khoá cho phép Bazel bỏ qua quá trình giải quyết 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 quả xây dựng, đặc biệt là trong các trường hợp mà việc phân giải có thể tốn thời gian.

  • Tính ổn định và giảm rủi ro. Tệp khoá giúp duy trì độ ổ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 những thay đổi có thể gây lỗi trong thư viện bên ngoài. Bằng cách khoá các phần phụ thuộc ở các phiên bản cụ thể, nguy cơ gây ra 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ử sẽ giảm thiểu.

Nội dung của tệp Lockfile

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. Dữ liệu này cũng bao gồm kết quả của quá trình xây dựng dự án ở trạng thái hiện tại. Tệp khoá bao gồm 2 phần chính:

  1. Các đầu vào của độ phân giải mô-đun, chẳng hạn như moduleFileHash, flagslocalOverrideHashes, cũng như đầu ra của độ phân giải là moduleDepGraph.
  2. Đối với mỗi tiện ích của mô-đun, tệp khoá bao gồm dữ liệu đầ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

Dưới đâ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": {
      "general": {
        "transitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
        "generatedRepoSpecs": {
          "hello": {
            "bzlFile": "@@//:extension.bzl",
            ...
          }
        }
      }
    },
    "//:extension.bzl%lockfile_ext2": {
      "os:macos": {
        "transitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
        "generatedRepoSpecs": {
          "hello": {
            "bzlFile": "@@//:extension.bzl",
            ...
          }
        }
      },
      "os:linux": {
        "transitiveDigest": "eWDzxG/aLsyY3Ubrto....+Jp4maQvEPxn0pLK=",
        "generatedRepoSpecs": {
          "hello": {
            "bzlFile": "@@//:extension.bzl",
            ...
          }
        }
      }
    }
  }
}

Hàm băm của 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, thì giá trị hàm băm sẽ khác nhau.

Cờ

Đối tượng Flags lưu trữ tất cả cờ có thể ảnh hưởng đến kết quả phân giải.

Hàm băm ghi đè cục bộ

Nếu mô-đun gốc có 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ộ. 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 quá trình phân giải bằng cách sử dụng dữ liệu đầu vào nêu trên. Tệp này tạo thành biểu đồ phần phụ thuộc của tất 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 sử dụng trong lệnh gọi hiện tại hoặc được 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 dùng nữa trên biểu đồ phần phụ thuộc, thì tiện ích đó sẽ bị xoá khỏi bản đồ moduleExtensions.

Nếu một tiện ích độc lập với loại hệ điều hành hoặc loại cấu trúc, thì phần này chỉ có một mục "chung". Nếu không, nhiều mục nhập sẽ được đưa vào, được đặt tên theo hệ điều hành, cấu trúc hoặc cả hai, trong đó mỗi mục tương ứng với kết quả đánh giá tiện ích trên các thông số cụ thể đó.

Mỗi mục trong bản đồ tiện ích tương ứng với một tiện ích đã sử dụng và được xác định bằng tệp và tên chứa tiện ích đó. Giá trị tương ứng của mỗi mục nhập chứa thông tin liên quan liên kết với phần mở rộng đó:

  1. transitiveDigest là chuỗi đại diện về việc triển khai tiện ích và các tệp .bzl bắc cầu của tiện ích đó.
  2. 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à số người sử dụng. Mặc dù không được lưu trữ trong tệp khoá, nhưng trường hợp sử dụng vẫn được cân nhắc 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á.

Những phương pháp hay nhất

Để khai thác tối đa lợi ích của tính năng tệp khoá, 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 các thay đổi trong cấu hình hoặ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 sẽ dựa trên tập hợp phần phụ thuộc mới nhất và chính xác nhất.

  • Đưa tệp khoá vào quy trình quản lý phiên bản để hỗ trợ việc 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á, thúc đẩy các môi trường phát triển nhất quán trên toàn dự án.

  • Sử dụng bazelisk để chạy Bazel và đưa tệp .bazelversion vào trình quản lý phiên bản chỉ định phiên bản Bazel tương ứng với tệp khoá. Vì Bazel là một phần phụ thuộc của bản dựng, nên tệp Lockfile sẽ dành riêng cho phiên bản Bazel và sẽ thay đổi ngay cả giữa các bản phát hành Bazel tương thích ngược. Việc sử dụng bazelisk đảm bảo rằng tất cả các nhà phát triển đang sử dụng phiên bản Bazel khớp với tệp khoá.

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 tệp bị khoá trong Bazel, giúp quy trình phát triển phần mềm mang tính cộng tác, đáng tin cậy và hiệu quả hơn.