คำถามที่พบบ่อย

หน้านี้จะตอบคำถามที่พบบ่อยบางส่วนเกี่ยวกับทรัพยากร Dependency ภายนอกใน Bazel

MODULE.bazel

ฉันควรกำหนดเวอร์ชันของโมดูล Bazel อย่างไร

การตั้งค่า version ด้วยคำสั่ง module ในที่เก็บต้นฉบับ MODULE.bazel อาจมีข้อเสียและผลข้างเคียงที่ไม่พึงประสงค์หลายประการหากไม่ ได้รับการจัดการอย่างระมัดระวัง

  • การทำซ้ำ: การเผยแพร่โมดูลเวอร์ชันใหม่มักเกี่ยวข้องกับการเพิ่มเวอร์ชันใน MODULE.bazel และการติดแท็กการเผยแพร่ ซึ่งเป็น 2 ขั้นตอนแยกกันที่อาจไม่ซิงค์กัน แม้ว่าการทำงานอัตโนมัติจะช่วยลดความเสี่ยงนี้ได้ แต่การหลีกเลี่ยงความเสี่ยงนี้ไปเลยจะง่ายและปลอดภัยกว่า

  • ความไม่สอดคล้องกัน: ผู้ใช้ที่ลบล้างโมดูลด้วยคอมมิตที่เฉพาะเจาะจงโดยใช้การลบล้างที่ไม่ใช่รีจิสทรีจะเห็นเวอร์ชันที่ไม่ถูกต้อง เช่น หากMODULE.bazelในที่เก็บต้นฉบับตั้งค่าเป็น version = "0.3.0" แต่มีการคอมมิตเพิ่มเติมตั้งแต่การเผยแพร่นั้น ผู้ใช้ที่ลบล้างด้วยคอมมิตใดคอมมิตหนึ่งจะยังคงเห็น 0.3.0 ในความเป็นจริงแล้ว เวอร์ชัน ควรแสดงให้เห็นว่าเวอร์ชันนั้นอยู่ก่อนการเผยแพร่ เช่น 0.3.1-rc1

  • ปัญหาการลบล้างที่ไม่ใช่รีจิสทรี: การใช้ค่าตัวยึดตำแหน่งอาจทำให้เกิดปัญหา เมื่อผู้ใช้ลบล้างโมดูลด้วยการลบล้างที่ไม่ใช่รีจิสทรี เช่น 0.0.0 จะไม่จัดเรียงเป็นเวอร์ชันสูงสุด ซึ่งโดยปกติแล้วจะเป็นลักษณะการทำงานที่ผู้ใช้ต้องการเมื่อทำการลบล้างที่ไม่ใช่รีจิสทรี

ดังนั้น คุณจึงควรหลีกเลี่ยงการตั้งค่าเวอร์ชันในที่เก็บต้นทาง MODULE.bazel แต่ให้ตั้งค่าใน MODULE.bazel ที่จัดเก็บไว้ในรีจิสทรี (เช่น Bazel Central Registry) ซึ่งเป็นแหล่งข้อมูลที่แท้จริงสำหรับ เวอร์ชันโมดูลในระหว่างการแก้ปัญหาการอ้างอิงภายนอกของ Bazel (ดูรีจิสทรีของ Bazel)

โดยปกติแล้วกระบวนการนี้จะทำงานโดยอัตโนมัติ เช่น ที่เก็บกฎตัวอย่าง rules-template ใช้ bazel-contrib/publish-to-bcr publish.yaml GitHub Action เพื่อ เผยแพร่รุ่นไปยัง BCR การดำเนินการนี้สร้างแพตช์สำหรับซอร์ส อาร์ไคฟ์ MODULE.bazel ที่มีเวอร์ชันที่เผยแพร่ ระบบจะจัดเก็บแพตช์นี้ไว้ในรีจิสทรีและใช้เมื่อดึงข้อมูลโมดูลระหว่างการแก้ปัญหาการอ้างอิงภายนอกของ Bazel

ด้วยวิธีนี้ ระบบจะตั้งค่าเวอร์ชันในรุ่นที่อยู่ในรีจิสทรีเป็นเวอร์ชันที่เผยแพร่แล้วอย่างถูกต้อง ดังนั้น bazel_dep, single_version_override และ multiple_version_override จะทำงานตามที่คาดไว้ ในขณะเดียวกันก็หลีกเลี่ยงปัญหาที่อาจเกิดขึ้นเมื่อทำการลบล้างที่ไม่ใช่รีจิสทรี เนื่องจากเวอร์ชันในที่เก็บถาวรของแหล่งที่มาจะเป็นค่าเริ่มต้น ('') ซึ่งระบบจะจัดการอย่างถูกต้องเสมอ (เนื่องจากเป็นค่าเวอร์ชันเริ่มต้น) และจะทำงานตามที่คาดไว้เมื่อจัดเรียง (ระบบจะถือว่าสตริงว่างเป็นเวอร์ชันสูงสุด)

ฉันควรเพิ่มระดับความเข้ากันได้เมื่อใด

ควรเพิ่ม compatibility_level ของโมดูล Bazel ในการคอมมิตเดียวกันที่ทำให้เกิดการเปลี่ยนแปลงที่ไม่เข้ากันแบบย้อนหลัง ("การเปลี่ยนแปลงที่ทำให้เกิดข้อขัดข้อง")

อย่างไรก็ตาม Bazel อาจแสดงข้อผิดพลาดหากตรวจพบว่ามีโมดูลเดียวกัน ที่มีระดับความเข้ากันได้แตกต่างกันอยู่ในกราฟการอ้างอิงที่แก้ไขแล้ว ซึ่งอาจเกิดขึ้นได้เมื่อโมดูล 2 โมดูลขึ้นไปขึ้นอยู่กับเวอร์ชันของโมดูลที่ 3 ที่มีระดับความเข้ากันได้แตกต่างกัน

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

เหตุใด MODULE.bazel จึงไม่รองรับ load

ในระหว่างการแก้ปัญหาการขึ้นต่อกัน ระบบจะดึงข้อมูลไฟล์ MODULE.bazel ของการขึ้นต่อกันภายนอกทั้งหมดที่อ้างอิงจากรีจิสทรี ในขั้นตอนนี้ ระบบยังไม่ได้ดึงข้อมูลที่เก็บถาวรต้นทางของ การอ้างอิง ดังนั้นหากไฟล์ MODULE.bazel loads ไฟล์อื่น Bazel จะไม่มีทางดึงข้อมูลไฟล์นั้นได้จริงโดยไม่ต้อง ดึงข้อมูลที่เก็บถาวรต้นฉบับทั้งหมด โปรดทราบว่าไฟล์ MODULE.bazel นั้นมีความพิเศษเนื่องจากโฮสต์อยู่ในรีจิสทรีโดยตรง

มี Use Case บางอย่างที่ผู้ใช้ที่ขอ loads ใน MODULE.bazel มักจะสนใจ และสามารถแก้ไขได้โดยไม่ต้องใช้ loads ดังนี้

  • การตรวจสอบว่าเวอร์ชันที่แสดงใน MODULE.bazel สอดคล้องกับข้อมูลเมตาของบิลด์ที่จัดเก็บไว้ที่อื่น เช่น ในไฟล์ .bzl ทำได้โดยใช้เมธอด native.module_version ในไฟล์ .bzl ที่โหลดจากไฟล์ BUILD
  • การแบ่งไฟล์ MODULE.bazel ขนาดใหญ่ออกเป็นส่วนๆ ที่จัดการได้ โดยเฉพาะอย่างยิ่งสำหรับ Monorepo: โมดูลรูทสามารถใช้ คำสั่ง include เพื่อแบ่งไฟล์ MODULE.bazel ออกเป็นหลายส่วน ด้วยเหตุผลเดียวกันนี้ เราจึงไม่อนุญาตให้ใช้ loadในไฟล์ MODULE.bazel และไม่สามารถใช้ include ในโมดูลที่ไม่ใช่รูท
  • ผู้ใช้ระบบ WORKSPACE เวอร์ชันเก่าอาจจำได้ว่าต้องประกาศที่เก็บ แล้วloadจากที่เก็บนั้นทันทีเพื่อดำเนินการตรรกะที่ซับซ้อน เราได้แทนที่ความสามารถนี้ด้วยส่วนขยายโมดูล

ฉันระบุช่วง SemVer สำหรับ bazel_dep ได้ไหม

ไม่ได้ ตัวจัดการแพ็กเกจอื่นๆ เช่น npm และ Cargo รองรับช่วงเวอร์ชัน (โดยนัยหรือโดยชัดแจ้ง) และมักต้องใช้ ตัวแก้ข้อจำกัด (ทำให้ผู้ใช้คาดเดาเอาต์พุตได้ยากขึ้น) และทำให้ การแก้ปัญหาเวอร์ชันไม่สามารถทำซ้ำได้หากไม่มีไฟล์ล็อก

แต่ Bazel ใช้การเลือกเวอร์ชันขั้นต่ำเหมือนกับ Go ซึ่งทำให้คาดการณ์เอาต์พุตได้ง่ายและรับประกัน ความสามารถในการทำซ้ำ นี่คือข้อแลกเปลี่ยนที่ตรงกับเป้าหมายการออกแบบของ Bazel

นอกจากนี้ เวอร์ชันโมดูล Bazel ยังเป็นซูเปอร์เซ็ตของ SemVer ด้วย ดังนั้นสิ่งที่สมเหตุสมผลในสภาพแวดล้อม SemVer ที่เข้มงวด จึงอาจไม่สมเหตุสมผลในเวอร์ชันโมดูล Bazel เสมอไป

ฉันจะรับ bazel_dep เวอร์ชันล่าสุดโดยอัตโนมัติได้ไหม

ผู้ใช้บางรายอาจขอระบุ bazel_dep(name = "foo", version = "latest") เพื่อรับเวอร์ชันล่าสุดของ dep โดยอัตโนมัติ ซึ่งคล้ายกับคำถามเกี่ยวกับช่วง SemVer และคำตอบก็คือไม่

โซลูชันที่แนะนำในที่นี้คือการใช้การทำงานอัตโนมัติเพื่อจัดการเรื่องนี้ ตัวอย่างเช่น Renovate รองรับ โมดูล Bazel

บางครั้งผู้ใช้ที่ถามคำถามนี้ต้องการหาวิธีทำซ้ำอย่างรวดเร็ว ในระหว่างการพัฒนาในเครื่อง ซึ่งทำได้โดยใช้ local_path_override

ทำไมจึงมี use_repo มากมาย

การใช้งานส่วนขยายโมดูลในไฟล์ MODULE.bazel บางครั้งมาพร้อมกับคำสั่ง use_repo ขนาดใหญ่ ตัวอย่างเช่น การใช้งานส่วนขยาย go_deps จาก gazelle โดยทั่วไปอาจมีลักษณะดังนี้

go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//:go.mod")
use_repo(
    go_deps,
    "com_github_gogo_protobuf",
    "com_github_golang_mock",
    "com_github_golang_protobuf",
    "org_golang_x_net",
    ...  # potentially dozens of lines...
)

คำสั่ง use_repo แบบยาวอาจดูซ้ำซ้อน เนื่องจากอาจมีข้อมูลอยู่ในไฟล์ go.mod ที่อ้างอิงอยู่แล้ว

เหตุผลที่ Bazel ต้องใช้คำสั่ง use_repo นี้ก็คือ Bazel จะเรียกใช้ส่วนขยายของโมดูลแบบเลื่อนเวลา กล่าวคือ ส่วนขยายโมดูลจะทำงานก็ต่อเมื่อมีการสังเกตผลลัพธ์ของส่วนขยายนั้น เท่านั้น เนื่องจาก "เอาต์พุต" ของส่วนขยายโมดูลคือคำจำกัดความของที่เก็บข้อมูล ซึ่งหมายความว่า เราจะเรียกใช้ส่วนขยายโมดูลก็ต่อเมื่อมีการขอที่เก็บข้อมูลที่ส่วนขยายนั้นกำหนดไว้ (เช่น หากมีการสร้างเป้าหมาย @org_golang_x_net//:foo ในตัวอย่าง ด้านบน) อย่างไรก็ตาม เราไม่ทราบว่าส่วนขยายโมดูลจะกำหนดที่เก็บใดจนกว่า หลังจากที่เราเรียกใช้แล้ว use_repo Directive จะมีประโยชน์ในกรณีนี้ ผู้ใช้สามารถ บอก Bazel ว่าต้องการให้ส่วนขยายสร้างที่เก็บใด และ Bazel จะ เรียกใช้ส่วนขยายเมื่อมีการใช้ที่เก็บที่เฉพาะเจาะจงเหล่านี้เท่านั้น

ส่วนขยายโมดูลสามารถส่งคืนออบเจ็กต์ extension_metadata จากฟังก์ชันการใช้งานเพื่อช่วยรักษาuse_repoคำสั่งนี้ ผู้ใช้สามารถเรียกใช้bazel mod tidy คำสั่งเพื่ออัปเดตคำสั่งuse_repoสำหรับส่วนขยายโมดูลเหล่านี้

การย้ายข้อมูล Bzlmod

ระบบจะประเมิน MODULE.bazel หรือ WORKSPACE ก่อน

เมื่อตั้งค่าทั้ง --enable_bzlmod และ --enable_workspace คุณอาจสงสัยว่าระบบใดจะได้รับการปรึกษาเป็นอันดับแรก คำตอบสั้นๆ คือระบบจะประเมิน MODULE.bazel (Bzlmod) ก่อน

คำตอบแบบยาวคือ "อะไรประเมินก่อน" ไม่ใช่คำถามที่ถูกต้อง คำถามที่ถูกต้องคือ ในบริบทของที่เก็บที่มีชื่อที่แน่นอน @@foo ชื่อที่เก็บที่เห็น @bar จะเปลี่ยนเป็นอะไร หรือการแมปที่เก็บของ @@base คืออะไร

ป้ายกำกับที่มีชื่อที่เก็บที่ชัดเจน (@ นำหน้าเพียงรายการเดียว) อาจอ้างอิงถึงสิ่งต่างๆ ตามบริบทที่ป้ายกำกับนั้นได้รับการแก้ไข เมื่อเห็นป้ายกำกับ @bar//:bazและสงสัยว่าป้ายกำกับนั้นชี้ไปที่ใด คุณต้องค้นหา ที่เก็บบริบทก่อน เช่น หากป้ายกำกับอยู่ในไฟล์ BUILD ที่อยู่ในที่เก็บ @@foo แสดงว่าที่เก็บบริบทคือ @@foo

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

  • หากที่เก็บบริบทเป็นที่เก็บหลัก (@@) ให้ทำดังนี้
    1. หาก bar เป็นชื่อ repo ที่ชัดเจนซึ่งแนะนำโดยไฟล์ MODULE.bazel ของโมดูลราก (ผ่าน bazel_dep, use_repo, module, use_repo_rule) แล้ว @bar จะเปลี่ยนเป็นสิ่งที่ไฟล์ MODULE.bazel นั้นอ้าง
    2. มิเช่นนั้น หาก bar เป็นที่เก็บที่กำหนดไว้ใน WORKSPACE (ซึ่งหมายความว่าชื่อที่แน่นอนคือ @@bar) @bar จะเปลี่ยนเป็น @@bar
    3. มิเช่นนั้น @bar จะเปลี่ยนเป็นค่าที่คล้ายกับ @@[unknown repo 'bar' requested from @@] และในที่สุดจะ ทำให้เกิดข้อผิดพลาด
  • หากรีโปบริบทเป็นรีโป Bzlmod-world (กล่าวคือ สอดคล้องกับโมดูล Bazel ที่ไม่ใช่รูท หรือสร้างขึ้นโดยส่วนขยายโมดูล) รีโปดังกล่าวจะเห็นเฉพาะรีโป Bzlmod-world อื่นๆ และไม่เห็นรีโป WORKSPACE-world
    • โปรดทราบว่ารวมถึงที่เก็บข้อมูลใดๆ ที่แนะนำในส่วนขยายโมดูลที่คล้ายกับ non_module_deps ในโมดูลรูท หรืออินสแตนซ์ use_repo_rule ในโมดูลรูท
  • หากกำหนดที่เก็บบริบทไว้ใน WORKSPACE ให้ทำดังนี้
    1. ก่อนอื่น ให้ตรวจสอบว่าคำจำกัดความของที่เก็บบริบทมีแอตทริบิวต์ magical repo_mapping หรือไม่ หากเป็นเช่นนั้น ให้ดำเนินการกับการแมปก่อน (ดังนั้นสำหรับ ที่เก็บที่กำหนดด้วย repo_mapping = {"@bar": "@baz"} เราจะดูที่ @baz ด้านล่าง)
    2. หาก bar เป็นชื่อ repo ที่ชัดเจนซึ่งระบุโดยไฟล์ MODULE.bazel ของโมดูลรูท @bar จะเปลี่ยนเป็นสิ่งที่ไฟล์ MODULE.bazel นั้นอ้าง (ซึ่งเหมือนกับข้อ 1 ในกรณีของที่เก็บหลัก)
    3. มิเช่นนั้น @bar จะเปลี่ยนเป็น @@bar ซึ่งส่วนใหญ่จะชี้ไปยัง รีโป bar ที่กำหนดไว้ใน WORKSPACE หากไม่ได้กำหนดรีโปดังกล่าว Bazel จะแสดงข้อผิดพลาด

หากต้องการดูเวอร์ชันที่กระชับกว่านี้ ให้ทำดังนี้

  • ที่เก็บ Bzlmod-world (ไม่รวมที่เก็บหลัก) จะเห็นเฉพาะที่เก็บ Bzlmod-world
  • ที่เก็บ WORKSPACE-world (รวมถึงที่เก็บหลัก) จะดูว่ารูท โมดูลใน Bzlmod world กำหนดอะไรไว้ก่อน จากนั้นจึงกลับไปดูที่เก็บ WORKSPACE-world

โปรดทราบว่าป้ายกำกับในบรรทัดคำสั่ง Bazel (รวมถึงแฟล็ก Starlark, ค่าแฟล็กประเภทป้ายกำกับ และรูปแบบเป้าหมายการสร้าง/ทดสอบ) จะถือว่ามีที่เก็บหลักเป็นที่เก็บบริบท

อื่นๆ

ฉันจะเตรียมและเรียกใช้การสร้างแบบออฟไลน์ได้อย่างไร

ใช้คำสั่ง bazel fetch เพื่อดึงข้อมูลล่วงหน้าของที่เก็บ คุณสามารถใช้แฟล็ก --repo (เช่น bazel fetch --repo @foo) เพื่อดึงเฉพาะรีโป @foo (ที่แก้ไขใน บริบทของรีโปหลัก ดูคำถาม ด้านบน) หรือใช้รูปแบบเป้าหมาย (เช่น bazel fetch @foo//:bar) เพื่อดึงข้อมูลการอ้างอิงแบบทรานซิทีฟทั้งหมดของ @foo//:bar (ซึ่งเทียบเท่ากับ bazel build --nobuild @foo//:bar)

หากต้องการตรวจสอบว่าไม่มีการดึงข้อมูลเกิดขึ้นระหว่างการบิลด์ ให้ใช้ --nofetch กล่าวอย่างเจาะจงคือ การดำเนินการนี้จะทำให้การพยายามเรียกใช้กฎของที่เก็บที่ไม่ใช่ในเครื่องล้มเหลว

หากต้องการดึงข้อมูลที่เก็บ และแก้ไขเพื่อทดสอบในเครื่อง ให้พิจารณาใช้คำสั่ง bazel vendor

ฉันจะใช้พร็อกซี HTTP ได้อย่างไร

Bazel จะใช้ตัวแปรสภาพแวดล้อม http_proxy และ HTTPS_PROXY ที่โปรแกรมอื่นๆ ยอมรับโดยทั่วไป เช่น curl

ฉันจะทำให้ Bazel ชอบ IPv6 ในการตั้งค่า IPv4/IPv6 แบบ 2 สแต็กได้อย่างไร

ในเครื่องที่ใช้ IPv6 เท่านั้น Bazel จะดาวน์โหลดการขึ้นต่อกันได้โดยไม่ต้องเปลี่ยนแปลงใดๆ อย่างไรก็ตาม ในเครื่อง IPv4/IPv6 แบบ Dual-stack Bazel จะใช้รูปแบบเดียวกันกับ Java โดยจะเลือกใช้ IPv4 หากเปิดใช้ ในบางสถานการณ์ เช่น เมื่อเครือข่าย IPv4 ไม่สามารถแก้ไข/เข้าถึงที่อยู่ภายนอกได้ อาจทำให้เกิดNetwork unreachableข้อยกเว้นและสร้างไม่สำเร็จ ในกรณีเหล่านี้ คุณสามารถลบล้างลักษณะการทำงานของ Bazel เพื่อให้ใช้ IPv6 ก่อนได้โดยใช้พร็อพเพอร์ตี้java.net.preferIPv6Addresses=trueของระบบ ดังนี้

  • ใช้--host_jvm_args=-Djava.net.preferIPv6Addresses=true ตัวเลือก startup เช่น โดยการเพิ่มบรรทัดต่อไปนี้ในไฟล์ .bazelrc

    startup --host_jvm_args=-Djava.net.preferIPv6Addresses=true

  • เมื่อเรียกใช้เป้าหมายการสร้าง Java ที่ต้องเชื่อมต่ออินเทอร์เน็ต (เช่น สำหรับการทดสอบการผสานรวม) ให้ใช้ --jvmopt=-Djava.net.preferIPv6Addresses=true tool flag เช่น ใส่ในไฟล์ .bazelrc

    build --jvmopt=-Djava.net.preferIPv6Addresses

  • หากคุณใช้ rules_jvm_external สำหรับ การแก้ปัญหาเวอร์ชันของ Dependency ให้เพิ่ม -Djava.net.preferIPv6Addresses=true ลงในตัวแปรสภาพแวดล้อม COURSIER_OPTS เพื่อระบุตัวเลือก JVM สำหรับ Coursier ด้วย

สามารถเรียกใช้กฎของที่เก็บจากระยะไกลด้วยการดำเนินการจากระยะไกลได้ไหม

ไม่ หรืออย่างน้อยก็ยังไม่ ผู้ใช้ที่ใช้บริการการดำเนินการจากระยะไกลเพื่อเพิ่มความเร็วในการสร้างอาจสังเกตเห็นว่ากฎของที่เก็บยังคงทำงานในเครื่อง เช่น ระบบจะดาวน์โหลด http_archive ลงในเครื่องก่อน (ใช้แคชการดาวน์โหลดในเครื่องหากมี) จากนั้นจะแตกไฟล์ แล้วอัปโหลดไฟล์ต้นฉบับแต่ละไฟล์ไปยังบริการการดำเนินการระยะไกลเป็นไฟล์อินพุต คุณอาจสงสัยว่า ทำไมบริการการดำเนินการจากระยะไกลไม่ดาวน์โหลดและแตกไฟล์เก็บถาวรนั้น เพื่อหลีกเลี่ยงการส่งคำขอที่ไม่จำเป็น

สาเหตุส่วนหนึ่งเป็นเพราะกฎของ repo (และส่วนขยายโมดูล) คล้ายกับ "สคริปต์" ที่ Bazel เรียกใช้เอง ตัวดำเนินการระยะไกลไม่จำเป็นต้อง ติดตั้ง Bazel ด้วยซ้ำ

อีกเหตุผลหนึ่งคือ Bazel มักต้องการไฟล์ BUILD ในไฟล์เก็บถาวรที่ดาวน์โหลดและ แตกไฟล์เพื่อทำการโหลดและวิเคราะห์ ซึ่งจะดำเนินการ ในเครื่อง

เรามีแนวคิดเบื้องต้นในการแก้ปัญหานี้ด้วยการปรับกฎของที่เก็บใหม่ให้เป็น กฎการสร้าง ซึ่งจะช่วยให้เรียกใช้กฎจากระยะไกลได้โดยอัตโนมัติ แต่ในทางกลับกัน ก็ทำให้เกิดข้อกังวลใหม่ๆ เกี่ยวกับสถาปัตยกรรม (เช่น คำสั่ง query อาจ ต้องเรียกใช้การดำเนินการ ซึ่งทำให้การออกแบบซับซ้อนขึ้น)

ดูการสนทนาก่อนหน้านี้เพิ่มเติมเกี่ยวกับหัวข้อนี้ได้ที่วิธีสนับสนุนที่เก็บ ที่ต้องใช้ Bazel ในการ ดึงข้อมูล