ฟีเจอร์ Lockfile ใน Bazel ช่วยให้สามารถบันทึกเวอร์ชันเฉพาะหรือการขึ้นต่อกันของไลบรารีซอฟต์แวร์หรือแพ็กเกจที่โปรเจ็กต์ต้องการ โซลูชันนี้ทำได้โดยการจัดเก็บผลลัพธ์ของการแก้ปัญหาโมดูลและการประเมินการขยายเวลา Lockfile ส่งเสริมบิลด์ที่ทำซ้ำได้ ซึ่งทำให้สภาพแวดล้อมการพัฒนามีความสอดคล้องกัน นอกจากนี้ ยังเพิ่มประสิทธิภาพในการสร้างโดยให้ Blazel ข้ามขั้นตอนการแก้ปัญหาเมื่อไม่มีการเปลี่ยนแปลงทรัพยากร Dependency ของโปรเจ็กต์ นอกจากนี้ Lockfile ยังปรับปรุงความเสถียรโดยป้องกันการอัปเดตที่ไม่คาดหมายหรือทำลายการเปลี่ยนแปลงในไลบรารีภายนอก ซึ่งจะช่วยลดความเสี่ยงในการเกิดข้อบกพร่อง
การสร้าง Lockfile
ระบบจะสร้าง Lockfile ภายใต้รูทของพื้นที่ทำงานที่ใช้ชื่อ MODULE.bazel.lock
โดยจะมีการสร้างหรืออัปเดตระหว่างกระบวนการบิลด์
โดยเฉพาะหลังจากการแก้ปัญหาโมดูลและการประเมินส่วนขยาย Lockfile จะเก็บข้อมูลสถานะปัจจุบันของโปรเจ็กต์ รวมถึงไฟล์ MODULE, แฟล็ก, การลบล้าง และข้อมูลอื่นๆ ที่เกี่ยวข้อง ที่สำคัญคือจะรวมเฉพาะการขึ้นต่อกันที่รวมอยู่ในการเรียกใช้ปัจจุบันของบิลด์เท่านั้น
เมื่อมีการเปลี่ยนแปลงในโปรเจ็กต์ที่มีผลต่อทรัพยากร Dependency ระบบจะอัปเดตไฟล์ล็อกโดยอัตโนมัติเพื่อแสดงสถานะใหม่ วิธีนี้ช่วยให้มั่นใจว่า Lockfile ยังคงมุ่งเน้นที่ชุดทรัพยากร Dependency ที่เฉพาะเจาะจงที่จำเป็นสำหรับบิลด์ปัจจุบัน ซึ่งจะแสดงทรัพยากร Dependency ที่แก้ไขแล้วของโปรเจ็กต์ได้อย่างถูกต้อง
การใช้งาน Lockfile
แฟล็ก --lockfile_mode
จะควบคุมไฟล์ล็อกไฟล์เหล่านั้นได้เพื่อปรับแต่งลักษณะการทำงานของ Bazel เมื่อสถานะของโปรเจ็กต์ต่างจากไฟล์ล็อก โหมดที่ใช้ได้มีดังนี้
update
(ค่าเริ่มต้น): หากสถานะของโปรเจ็กต์ตรงกับ Lockfile ระบบจะแสดงผลการแก้ปัญหาจาก Lockfile ทันที มิเช่นนั้น ระบบจะดำเนินการแก้ปัญหาและอัปเดตไฟล์ล็อกเพื่อแสดงสถานะปัจจุบันerror
: หากสถานะของโปรเจ็กต์ตรงกับ Lockfile ระบบจะแสดงผลการแก้ปัญหาจาก Lockfile ไม่เช่นนั้น Bazel จะแสดงข้อผิดพลาดที่ระบุความแตกต่างระหว่างโปรเจ็กต์และไฟล์ Lock โหมดนี้จะมีประโยชน์อย่างยิ่งเมื่อคุณต้องการตรวจสอบว่าทรัพยากร Dependency ของโปรเจ็กต์ไม่มีการเปลี่ยนแปลง และระบบจะถือว่าความแตกต่างทั้งหมดเป็นข้อผิดพลาดoff
: ไม่ตรวจสอบ Lockfile เลย
ประโยชน์ของ Lockfile
Lockfile มีประโยชน์หลายอย่างและสามารถใช้ได้หลากหลายวิธี ดังนี้
บิลด์ที่ทำซ้ำได้ การบันทึกเวอร์ชันที่เฉพาะเจาะจงหรือทรัพยากร Dependency ของไลบรารีซอฟต์แวร์ ช่วยให้คุณล็อกไฟล์เพื่อให้แน่ใจว่าบิลด์สามารถเกิดซ้ำได้ในสภาพแวดล้อมต่างๆ เมื่อเวลาผ่านไป นักพัฒนาซอฟต์แวร์อาศัยผลลัพธ์ที่สม่ำเสมอและคาดการณ์ได้เมื่อสร้างโปรเจ็กต์
การข้ามการแก้ปัญหาที่มีประสิทธิภาพ Lockfile ช่วยให้ Bazel ข้ามกระบวนการแก้ปัญหาหากไม่มีการเปลี่ยนแปลงทรัพยากร Dependency ของโปรเจ็กต์ตั้งแต่บิลด์ครั้งล่าสุด วิธีนี้ช่วยปรับปรุงประสิทธิภาพของการสร้างได้อย่างมาก โดยเฉพาะอย่างยิ่งในสถานการณ์ที่การแก้ปัญหาใช้เวลานาน
ความเสถียรและการลดความเสี่ยง Lockfile ช่วยรักษาความเสถียรโดยการป้องกันการอัปเดตที่ไม่คาดคิดหรือทำให้การเปลี่ยนแปลงในไลบรารีภายนอกเสียหาย การล็อกทรัพยากร Dependency เฉพาะเวอร์ชันที่เฉพาะเจาะจง ความเสี่ยงของการเกิดข้อบกพร่องเนื่องจากการอัปเดตที่ใช้ร่วมกันไม่ได้หรือยังไม่ได้ทดสอบจะลดลง
เนื้อหาของ Lockfile
Lockfile มีข้อมูลที่จำเป็นทั้งหมดในการตรวจสอบว่าสถานะของโปรเจ็กต์มีการเปลี่ยนแปลงหรือไม่ และยังรวมถึงผลของการสร้างโปรเจ็กต์ในสถานะปัจจุบันด้วย Lockfile ประกอบด้วยส่วนหลัก 2 ส่วน ได้แก่
- อินพุตของความละเอียดโมดูล เช่น
moduleFileHash
,flags
และlocalOverrideHashes
รวมทั้งเอาต์พุตของความละเอียด ซึ่งก็คือmoduleDepGraph
- สำหรับส่วนขยายโมดูลแต่ละรายการ 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": {
"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",
...
}
}
}
}
}
}
แฮชไฟล์โมดูล
moduleFileHash
แสดงแฮชของเนื้อหาไฟล์ MODULE.bazel
หากมีการเปลี่ยนแปลงในไฟล์นี้ ค่าแฮชจะแตกต่างไป
ธง
ออบเจ็กต์ Flags
จะจัดเก็บแฟล็กทั้งหมดที่อาจส่งผลต่อผลลัพธ์ความละเอียด
แฮชการลบล้างในเครื่อง
หากโมดูลรูทมี local_path_overrides
ส่วนนี้จะจัดเก็บแฮชของไฟล์ MODULE.bazel
ไว้ในที่เก็บในเครื่อง ช่วยให้ติดตามการเปลี่ยนแปลง
ในทรัพยากร Dependency นี้
กราฟการอ้างอิงโมดูล
moduleDepGraph
แสดงผลลัพธ์ของกระบวนการแก้ไขโดยใช้ข้อมูลที่กล่าวถึงข้างต้น ซึ่งจะสร้างกราฟการอ้างอิงของโมดูลทั้งหมดที่จำเป็นต่อการเรียกใช้โปรเจ็กต์
ส่วนขยายโมดูล
ส่วน moduleExtensions
เป็นแผนที่ซึ่งมีเฉพาะส่วนขยายที่ใช้ในการเรียกใช้ปัจจุบันหรือที่เรียกใช้ก่อนหน้านี้ โดยยกเว้นส่วนขยายที่ไม่ได้ใช้อีกต่อไป กล่าวคือ หากไม่มีการใช้งานส่วนขยายใดๆ ในกราฟการอ้างอิง ระบบจะนำส่วนขยายนั้นออกจากแผนที่ moduleExtensions
หากส่วนขยายไม่เกี่ยวข้องกับระบบปฏิบัติการหรือประเภทสถาปัตยกรรม ส่วนนี้จะแสดงเฉพาะรายการ "ทั่วไป" รายการเดียว ไม่เช่นนั้นก็จะรวมหลายรายการเข้าด้วยกัน โดยตั้งชื่อตามระบบปฏิบัติการ สถาปัตยกรรม หรือทั้งคู่ โดยแต่ละรายการจะสอดคล้องกับผลลัพธ์ของการประเมินส่วนขยายในข้อมูลจำเพาะเหล่านั้น
แต่ละรายการในแผนที่ส่วนขยายจะสอดคล้องกับส่วนขยายที่ใช้ และระบุด้วยไฟล์และชื่อไฟล์นั้นๆ ค่าที่สอดคล้องกันสำหรับแต่ละรายการจะมีข้อมูลที่เกี่ยวข้องซึ่งเชื่อมโยงกับส่วนขยายนั้น:
transitiveDigest
ข้อมูลสรุปเกี่ยวกับการใช้งานส่วนขยายและไฟล์ .bzl แบบผกผันgeneratedRepoSpecs
ผลลัพธ์ของการเรียกใช้ส่วนขยายนั้นด้วยอินพุตปัจจุบัน
ปัจจัยเพิ่มเติมที่อาจส่งผลต่อผลลัพธ์ของส่วนขยายคือการใช้งานของส่วนขยาย แม้ว่าจะไม่มีการจัดเก็บไว้ใน Lockfile แต่จะมีการพิจารณาการใช้งานเมื่อเปรียบเทียบสถานะปัจจุบันของส่วนขยายกับไฟล์ใน Lockfile
แนวทางปฏิบัติแนะนำ
ลองทําตามแนวทางปฏิบัติแนะนําต่อไปนี้เพื่อให้ได้รับประโยชน์สูงสุดจากฟีเจอร์ Lockfile
อัปเดต Lockfile เป็นประจำเพื่อแสดงการเปลี่ยนแปลงในทรัพยากร Dependency หรือการกำหนดค่าของโปรเจ็กต์ วิธีนี้ช่วยให้มั่นใจว่าบิลด์ต่อๆ มาจะอิงตามชุดทรัพยากร Dependency ที่เป็นปัจจุบันและถูกต้องที่สุด
รวม Lockfile ในการควบคุมเวอร์ชันเพื่ออำนวยความสะดวกในการทำงานร่วมกันและดูแลให้สมาชิกในทีมทุกคนมีสิทธิ์เข้าถึงไฟล์ล็อกเดียวกัน ซึ่งจะส่งเสริมให้มีสภาพแวดล้อมการพัฒนาที่สอดคล้องกันทั้งโปรเจ็กต์
ใช้
bazelisk
เพื่อเรียกใช้ Bazel และใส่ไฟล์.bazelversion
ในการควบคุมเวอร์ชันที่ระบุเวอร์ชัน Bazel ที่ตรงกับไฟล์ล็อก เนื่องจากตัว Bazel เป็นทรัพยากร Dependency ของบิลด์ ไฟล์ Lockfile จึงมีไว้สำหรับเวอร์ชัน Bazel เท่านั้นและจะเปลี่ยนแปลงแม้กระทั่งระหว่างรุ่น Bazel ที่เข้ากันได้แบบย้อนหลัง การใช้bazelisk
จะช่วยให้มั่นใจว่านักพัฒนาซอฟต์แวร์ทั้งหมดใช้เวอร์ชัน Bazel ที่ตรงกับ Lockfile
เมื่อทำตามแนวทางปฏิบัติแนะนำเหล่านี้ คุณจะสามารถใช้ฟีเจอร์ Lockfile ใน Bazel ได้อย่างมีประสิทธิภาพ ซึ่งนำไปสู่เวิร์กโฟลว์การพัฒนาซอฟต์แวร์ที่ทำงานร่วมกันและมีประสิทธิภาพมากขึ้น