ไฟล์ Bazel Lock

ฟีเจอร์ Lockfile ใน Bazel ช่วยให้บันทึกเวอร์ชันหรือทรัพยากร Dependency ที่เฉพาะเจาะจงของไลบรารีหรือแพ็กเกจซอฟต์แวร์ที่โปรเจ็กต์ต้องใช้ได้ โดยจะจัดเก็บผลลัพธ์ของการแก้ปัญหาโมดูลและการประเมินส่วนขยาย Lockfile ช่วยให้สร้างบิลด์ซ้ำได้และช่วยให้สภาพแวดล้อมการพัฒนาสอดคล้องกัน นอกจากนี้ ยังช่วยเพิ่มประสิทธิภาพของบิลด์ด้วยการอนุญาตให้ Bazel ข้ามกระบวนการแก้ปัญหาเมื่อไม่มีการเปลี่ยนแปลงในทรัพยากร Dependency ของโปรเจ็กต์ ยิ่งไปกว่านั้น Lockfile ยังช่วยปรับปรุงเสถียรภาพด้วยการป้องกันการอัปเดตที่ไม่คาดคิดหรือการเปลี่ยนแปลงที่ทำให้เกิดข้อผิดพลาดในไลบรารีภายนอก ซึ่งจะช่วยลดความเสี่ยงในการเกิดข้อบกพร่อง

การสร้าง Lockfile

ระบบจะสร้าง Lockfile ไว้ที่รูทของพื้นที่ทำงานโดยใช้ชื่อ MODULE.bazel.lock โดยจะสร้างหรืออัปเดตระหว่างกระบวนการบิลด์ ซึ่งจะเกิดขึ้นหลังจากแก้ปัญหาโมดูลและประเมินส่วนขยาย Lockfile จะบันทึกสถานะปัจจุบันของโปรเจ็กต์ ซึ่งรวมถึงไฟล์ MODULE, แฟล็ก, การลบล้าง และข้อมูลอื่นๆ ที่เกี่ยวข้อง สิ่งสำคัญคือ Lockfile จะมีเฉพาะทรัพยากร Dependency ที่รวมอยู่ในการเรียกใช้บิลด์ปัจจุบัน

เมื่อมีการเปลี่ยนแปลงในโปรเจ็กต์ที่ส่งผลต่อทรัพยากร Dependency ระบบจะอัปเดต Lockfile โดยอัตโนมัติเพื่อให้แสดงสถานะใหม่ ซึ่งจะช่วยให้ Lockfile มุ่งเน้นไปที่ทรัพยากร Dependency ชุดเฉพาะที่จำเป็นสำหรับบิลด์ปัจจุบัน และแสดงทรัพยากร Dependency ที่แก้ปัญหาแล้วของโปรเจ็กต์ได้อย่างถูกต้อง

การใช้ Lockfile

คุณสามารถควบคุม Lockfile ได้ด้วยแฟล็ก --lockfile_mode เพื่อ ปรับแต่งลักษณะการทำงานของ Bazel เมื่อสถานะโปรเจ็กต์แตกต่างจาก Lockfile โหมดที่ใช้ได้มีดังนี้

  • update (ค่าเริ่มต้น): หากสถานะโปรเจ็กต์ตรงกับ Lockfile ระบบจะแสดงผลลัพธ์การแก้ปัญหาจาก Lockfile ทันที มิเช่นนั้น ระบบจะดำเนินการแก้ปัญหาและอัปเดต Lockfile เพื่อแสดงสถานะปัจจุบัน
  • error: หากสถานะโปรเจ็กต์ตรงกับ Lockfile ระบบจะแสดงผลลัพธ์การแก้ปัญหาจาก Lockfile มิเช่นนั้น Bazel จะแสดงข้อผิดพลาดที่ระบุความแตกต่างระหว่างโปรเจ็กต์กับ Lockfile โหมดนี้มีประโยชน์อย่างยิ่งเมื่อคุณต้องการให้ทรัพยากร Dependency ของโปรเจ็กต์ไม่เปลี่ยนแปลง และถือว่าความแตกต่างใดๆ เป็นข้อผิดพลาด
  • off: ระบบจะไม่ตรวจสอบ Lockfile เลย

ประโยชน์ของ Lockfile

Lockfile มีประโยชน์หลายประการและใช้ได้หลายวิธี ดังนี้

  • สร้างบิลด์ซ้ำได้ Lockfile จะบันทึกเวอร์ชันหรือทรัพยากร Dependency ที่เฉพาะเจาะจงของไลบรารีซอฟต์แวร์ ซึ่งจะช่วยให้สร้างบิลด์ซ้ำได้ในสภาพแวดล้อมต่างๆ และเมื่อเวลาผ่านไป นักพัฒนาแอปสามารถมั่นใจได้ว่าจะได้ผลลัพธ์ที่สอดคล้องและคาดการณ์ได้เมื่อสร้างโปรเจ็กต์

  • ข้ามการแก้ปัญหาได้อย่างมีประสิทธิภาพ Lockfile ช่วยให้ Bazel ข้ามกระบวนการแก้ปัญหาได้หากไม่มีการเปลี่ยนแปลงในทรัพยากร Dependency ของโปรเจ็กต์ตั้งแต่การสร้างบิลด์ครั้งล่าสุด ซึ่งจะช่วยเพิ่มประสิทธิภาพของบิลด์ได้อย่างมาก โดยเฉพาะอย่างยิ่งในสถานการณ์ที่การแก้ปัญหาอาจใช้เวลานาน

  • เสถียรภาพและการลดความเสี่ยง Lockfile ช่วยรักษาเสถียรภาพด้วยการป้องกันการอัปเดตที่ไม่คาดคิดหรือการเปลี่ยนแปลงที่ทำให้เกิดข้อผิดพลาดในไลบรารีภายนอก การล็อกทรัพยากร Dependency ไว้ที่เวอร์ชันที่เฉพาะเจาะจงจะช่วยลดความเสี่ยงในการเกิดข้อบกพร่องเนื่องจากการอัปเดตที่ไม่เข้ากันหรือยังไม่ได้ทดสอบ

เนื้อหาของ Lockfile

Lockfile มีข้อมูลที่จำเป็นทั้งหมดเพื่อระบุว่าสถานะโปรเจ็กต์มีการเปลี่ยนแปลงหรือไม่ นอกจากนี้ ยังมีผลลัพธ์ของการสร้างโปรเจ็กต์ในสถานะปัจจุบันด้วย Lockfile ประกอบด้วย 2 ส่วนหลัก ดังนี้

  1. อินพุตของการแก้ปัญหาโมดูล เช่น moduleFileHash, flags และ localOverrideHashes รวมถึงเอาต์พุตของการแก้ปัญหา ซึ่งก็คือ moduleDepGraph
  2. สำหรับส่วนขยายโมดูลแต่ละรายการ Lockfile จะมีอินพุตที่ส่งผลต่อส่วนขยายนั้น ซึ่งแสดงด้วย 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 ในที่เก็บในเครื่อง ซึ่งจะช่วยให้ติดตามการเปลี่ยนแปลงทรัพยากร Dependency นี้ได้

กราฟทรัพยากร Dependency ของโมดูล

moduleDepGraph แสดงผลลัพธ์ของกระบวนการแก้ปัญหาโดยใช้ข้อมูลอินพุตที่กล่าวถึงข้างต้น ซึ่งจะสร้างกราฟทรัพยากร Dependency ของโมดูลทั้งหมดที่จำเป็นต่อการเรียกใช้โปรเจ็กต์

ส่วนขยายโมดูล

ส่วน moduleExtensions เป็นแผนที่ที่มีเฉพาะส่วนขยายที่ใช้ในการเรียกใช้ปัจจุบันหรือที่เรียกใช้ก่อนหน้านี้ โดยไม่รวมส่วนขยายที่ไม่ได้ใช้อีกต่อไป กล่าวอีกนัยหนึ่งคือ หากไม่มีการใช้ส่วนขยายในกราฟทรัพยากร Dependency อีกต่อไป ระบบจะนำส่วนขยายนั้นออกจากแผนที่ moduleExtensions

รายการแต่ละรายการในแผนที่นี้สอดคล้องกับส่วนขยายที่ใช้และระบุด้วยไฟล์และชื่อที่มีส่วนขยายนั้น ค่าที่สอดคล้องกับแต่ละรายการจะมีข้อมูลที่เกี่ยวข้องกับส่วนขยายนั้น ดังนี้

  1. transitiveDigest คือ Digest ของการใช้งานส่วนขยายและไฟล์ .bzl แบบ Transitive
  2. generatedRepoSpecs คือผลลัพธ์ของการเรียกใช้ส่วนขยายนั้นด้วยอินพุตปัจจุบัน

อีกปัจจัยหนึ่งที่อาจส่งผลต่อผลลัพธ์ของส่วนขยายคือ การใช้งาน แม้ว่าจะไม่ได้จัดเก็บไว้ใน Lockfile แต่ระบบจะพิจารณาการใช้งานเมื่อเปรียบเทียบสถานะปัจจุบันของส่วนขยายกับสถานะใน Lockfile

แนวทางปฏิบัติแนะนำ

โปรดพิจารณาแนวทางปฏิบัติแนะนำต่อไปนี้เพื่อใช้ประโยชน์จากฟีเจอร์ Lockfile ให้ได้มากที่สุด

  • อัปเดต Lockfile เป็นประจำเพื่อให้แสดงการเปลี่ยนแปลงในทรัพยากร Dependency หรือการกำหนดค่าของโปรเจ็กต์ ซึ่งจะช่วยให้การสร้างบิลด์ในภายหลังอิงตามทรัพยากร Dependency ชุดที่ถูกต้องและเป็นปัจจุบันที่สุด

  • รวม Lockfile ไว้ในการควบคุมเวอร์ชันเพื่ออำนวยความสะดวกในการทำงานร่วมกันและตรวจสอบว่าสมาชิกทุกคนในทีมมีสิทธิ์เข้าถึง Lockfile เดียวกัน ซึ่งจะช่วยให้สภาพแวดล้อมการพัฒนาสอดคล้องกันในโปรเจ็กต์

การทำตามแนวทางปฏิบัติแนะนำเหล่านี้จะช่วยให้คุณใช้ฟีเจอร์ Lockfile ใน Bazel ได้อย่างมีประสิทธิภาพ ซึ่งจะนำไปสู่เวิร์กโฟลว์การพัฒนาซอฟต์แวร์ที่มีประสิทธิภาพ เชื่อถือได้ และทำงานร่วมกันได้มากขึ้น