การย้ายข้อมูลจาก Maven ไปยัง Bazel

หน้านี้จะอธิบายวิธีย้ายข้อมูลจาก Maven ไปยัง Bazel รวมถึงข้อกำหนดเบื้องต้นและขั้นตอนการติดตั้ง โดยจะอธิบายความแตกต่างระหว่าง Maven กับ Bazel และแสดงตัวอย่างการย้ายข้อมูลโดยใช้โปรเจ็กต์ Guava

เมื่อย้ายข้อมูลจากเครื่องมือบิลด์ใดๆ ไปยัง Bazel วิธีที่ดีที่สุดคือการเรียกใช้เครื่องมือบิลด์ทั้ง 2 รายการแบบขนานกันจนกว่าคุณจะย้ายข้อมูลทีมพัฒนา ระบบ CI และระบบอื่นๆ ที่เกี่ยวข้องทั้งหมดเสร็จสมบูรณ์ คุณสามารถเรียกใช้ Maven และ Bazel ในที่เก็บเดียวกันได้

ก่อนเริ่มต้น

ความแตกต่างระหว่าง Maven กับ Bazel

  • Maven ใช้ไฟล์ pom.xml ระดับบนสุด Bazel รองรับไฟล์บิลด์และเป้าหมายหลายรายการต่อไฟล์ BUILD ซึ่งช่วยให้บิลด์เพิ่มขึ้นได้มากกว่า Maven
  • Maven จะดูแลขั้นตอนต่างๆ ของกระบวนการใช้งาน Bazel ไม่ได้ทำให้การใช้งานเป็นไปโดยอัตโนมัติ
  • Bazel ช่วยให้คุณแสดงทรัพยากร Dependency ระหว่างภาษาต่างๆ ได้
  • เมื่อเพิ่มส่วนใหม่ลงในโปรเจ็กต์ คุณอาจต้องเพิ่มไฟล์ BUILD ใหม่ด้วย Bazel แนวทางปฏิบัติแนะนำคือการเพิ่มไฟล์ BUILD ลงในแพ็กเกจ Java ใหม่แต่ละรายการ

ย้ายข้อมูลจาก Maven ไปยัง Bazel

ขั้นตอนด้านล่างจะอธิบายวิธีย้ายข้อมูลโปรเจ็กต์ไปยัง Bazel

  1. สร้างไฟล์ MODULE.bazel
  2. สร้างไฟล์ BUILD 1 ไฟล์
  3. สร้างไฟล์ BUILD เพิ่มเติม
  4. สร้างโดยใช้ Bazel

ตัวอย่างด้านล่างมาจากการย้ายข้อมูลโปรเจ็กต์ Guava project จาก Maven ไปยัง Bazel โปรเจ็กต์ Guava ที่ใช้คือเวอร์ชัน v31.1 ตัวอย่างที่ใช้ Guava จะไม่แสดงแต่ละขั้นตอนในการย้ายข้อมูล แต่จะแสดงไฟล์และเนื้อหาที่สร้างขึ้นหรือเพิ่มด้วยตนเองสำหรับการย้ายข้อมูล

$ git clone https://github.com/google/guava.git && cd guava
$ git checkout v31.1

1. สร้างไฟล์ MODULE.bazel

สร้างไฟล์ชื่อ MODULE.bazel ที่รูทของโปรเจ็กต์ หากโปรเจ็กต์ไม่มีทรัพยากร Dependency ภายนอก คุณสามารถเว้นว่างไฟล์นี้ได้

หากโปรเจ็กต์ขึ้นอยู่กับไฟล์หรือแพ็กเกจที่ไม่ได้อยู่ในไดเรกทอรีใดไดเรกทอรีหนึ่งของโปรเจ็กต์ ให้ระบุทรัพยากร Dependency ภายนอกเหล่านี้ในไฟล์ MODULE.bazel คุณสามารถใช้ rules_jvm_external เพื่อจัดการทรัพยากร Dependency จาก Maven ดูวิธีการใช้ชุดกฎนี้ได้ที่ the README .

ตัวอย่างโปรเจ็กต์ Guava: ทรัพยากร Dependency ภายนอก

คุณสามารถแสดงรายการทรัพยากร Dependency ภายนอกของโปรเจ็กต์ Guava ด้วยชุดกฎ rules_jvm_external

เพิ่มข้อมูลโค้ดต่อไปนี้ลงในไฟล์ MODULE.bazel

bazel_dep(name = "rules_jvm_external", version = "6.2")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
maven.install(
    artifacts = [
        "com.google.code.findbugs:jsr305:3.0.2",
        "com.google.errorprone:error_prone_annotations:2.11.0",
        "com.google.j2objc:j2objc-annotations:1.3",
        "org.codehaus.mojo:animal-sniffer-annotations:1.20",
        "org.checkerframework:checker-qual:3.12.0",
    ],
    repositories = [
        "https://repo1.maven.org/maven2",
    ],
)
use_repo(maven, "maven")

2. สร้างไฟล์ BUILD 1 ไฟล์

เมื่อกำหนดพื้นที่ทำงานและแสดงรายการทรัพยากร Dependency ภายนอก (หากมี) แล้ว คุณต้องสร้างไฟล์ BUILD เพื่ออธิบายวิธีสร้างโปรเจ็กต์ Bazel สามารถใช้ไฟล์ BUILD หลายไฟล์เพื่อสร้างโปรเจ็กต์ได้ ซึ่งแตกต่างจาก Maven ที่ใช้ไฟล์ pom.xml เพียงไฟล์เดียว ไฟล์เหล่านี้จะระบุเป้าหมายบิลด์หลายรายการ ซึ่งช่วยให้ Bazel สร้างบิลด์ที่เพิ่มขึ้นได้

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

  1. สร้างไฟล์ข้อความและตั้งชื่อว่า BUILD ในไดเรกทอรีเดียวกับไฟล์ MODULE.bazel

  2. ในไฟล์ BUILD นี้ ให้ใช้กฎที่เหมาะสมเพื่อสร้างเป้าหมาย 1 รายการสำหรับสร้างโปรเจ็กต์ เคล็ดลับบางส่วนมีดังนี้

    • ใช้กฎที่เหมาะสม

      • หากต้องการสร้างโปรเจ็กต์ที่มีโมดูล Maven เดียว ให้ใช้กฎ java_library ดังนี้

        java_library(
           name = "everything",
           srcs = glob(["src/main/java/**/*.java"]),
           resources = glob(["src/main/resources/**"]),
           deps = ["//:all-external-targets"],
        )
        
      • หากต้องการสร้างโปรเจ็กต์ที่มีโมดูล Maven หลายรายการ ให้ใช้กฎ java_library ดังนี้

        java_library(
           name = "everything",
           srcs = glob([
                 "Module1/src/main/java/**/*.java",
                 "Module2/src/main/java/**/*.java",
                 ...
           ]),
           resources = glob([
                 "Module1/src/main/resources/**",
                 "Module2/src/main/resources/**",
                 ...
           ]),
           deps = ["//:all-external-targets"],
        )
        
      • หากต้องการสร้างไบนารี ให้ใช้กฎ java_binary ดังนี้

        java_binary(
           name = "everything",
           srcs = glob(["src/main/java/**/*.java"]),
           resources = glob(["src/main/resources/**"]),
           deps = ["//:all-external-targets"],
           main_class = "com.example.Main"
        )
        
      • ระบุแอตทริบิวต์

        • name: ตั้งชื่อเป้าหมายให้สื่อความหมาย ในตัวอย่างด้านบน เป้าหมายมีชื่อว่า "everything"
        • srcs: ใช้ globbing เพื่อแสดงรายการไฟล์ .java ทั้งหมดในโปรเจ็กต์
        • resources: ใช้ globbing เพื่อแสดงรายการทรัพยากรทั้งหมดในโปรเจ็กต์
        • deps: คุณต้องกำหนดทรัพยากร Dependency ภายนอกที่โปรเจ็กต์ต้องการ
      • ดูตัวอย่างไฟล์ BUILD ระดับบนสุดนี้จากการย้ายข้อมูลโปรเจ็กต์ Guava ด้านล่าง

  3. เมื่อมีไฟล์ BUILD ที่รูทของโปรเจ็กต์แล้ว ให้สร้างโปรเจ็กต์เพื่อให้แน่ใจว่าโปรเจ็กต์ทำงานได้ ในบรรทัดคำสั่ง ให้ใช้ bazel build //:everything จากไดเรกทอรีพื้นที่ทำงานเพื่อสร้างโปรเจ็กต์ด้วย Bazel

    ตอนนี้โปรเจ็กต์สร้างขึ้นด้วย Bazel เรียบร้อยแล้ว คุณจะต้องเพิ่มไฟล์ BUILD เพิ่มเติมเพื่อให้โปรเจ็กต์สร้างขึ้นได้

ตัวอย่างโปรเจ็กต์ Guava: เริ่มต้นด้วยไฟล์ BUILD 1 ไฟล์

เมื่อย้ายข้อมูลโปรเจ็กต์ Guava ไปยัง Bazel ระบบจะใช้ไฟล์ BUILD 1 ไฟล์ในตอนแรกเพื่อสร้างโปรเจ็กต์ทั้งหมด นี่คือเนื้อหาของไฟล์ BUILD เริ่มต้นนี้ในไดเรกทอรีพื้นที่ทำงาน

java_library(
    name = "everything",
    srcs = glob([
        "guava/src/**/*.java",
        "futures/failureaccess/src/**/*.java",
    ]),
    javacopts = ["-XepDisableAllChecks"],
    deps = [
        "@maven//:com_google_code_findbugs_jsr305",
        "@maven//:com_google_errorprone_error_prone_annotations",
        "@maven//:com_google_j2objc_j2objc_annotations",
        "@maven//:org_checkerframework_checker_qual",
        "@maven//:org_codehaus_mojo_animal_sniffer_annotations",
    ],
)

3. สร้างไฟล์ BUILD เพิ่มเติม (ไม่บังคับ)

Bazel ทำงานได้โดยใช้ BUILD file เพียงไฟล์เดียว ดังที่คุณเห็นหลังจากบิลด์ครั้งแรกเสร็จสมบูรณ์ อย่างไรก็ตาม คุณควรพิจารณาแบ่งบิลด์ออกเป็นส่วนย่อยๆ โดยเพิ่มไฟล์ BUILD ที่มีเป้าหมายที่ละเอียดยิ่งขึ้น

ไฟล์ BUILD หลายไฟล์ที่มีเป้าหมายหลายรายการจะทำให้บิลด์มีความละเอียดเพิ่มขึ้น ซึ่งจะช่วยให้

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

เคล็ดลับในการเพิ่มไฟล์ BUILD เพิ่มเติม

  • คุณสามารถเริ่มต้นด้วยการเพิ่มไฟล์ BUILD ลงในแพ็กเกจ Java แต่ละรายการ เริ่มต้นด้วยแพ็กเกจ Java ที่มีทรัพยากร Dependency น้อยที่สุด แล้วค่อยๆ เพิ่มไปยังแพ็กเกจที่มีทรัพยากร Dependency มากที่สุด
  • เมื่อเพิ่มไฟล์ BUILD และระบุเป้าหมาย ให้เพิ่มเป้าหมายใหม่เหล่านี้ลงในส่วน deps ของเป้าหมายที่ขึ้นอยู่กับเป้าหมายใหม่ โปรดทราบว่าฟังก์ชัน glob() จะไม่ข้ามขอบเขตของแพ็กเกจ ดังนั้นเมื่อจำนวนแพ็กเกจเพิ่มขึ้น ไฟล์ที่ตรงกับ glob() จะลดลง
  • ทุกครั้งที่เพิ่มไฟล์ BUILD ลงในไดเรกทอรี main ให้ตรวจสอบว่าคุณได้เพิ่มไฟล์ BUILD ลงในไดเรกทอรี test ที่เกี่ยวข้องแล้ว
  • ระมัดระวังในการจำกัดการมองเห็นระหว่างแพ็กเกจอย่างเหมาะสม
  • เพื่อให้การแก้ปัญหาข้อผิดพลาดในการตั้งค่าไฟล์ BUILD ง่ายขึ้น ให้ตรวจสอบว่าโปรเจ็กต์ยังคงสร้างด้วย Bazel ได้เมื่อคุณเพิ่มไฟล์บิลด์แต่ละไฟล์ เรียกใช้ bazel build //... เพื่อให้แน่ใจว่าเป้าหมายทั้งหมดจะยังคงสร้างได้

4. สร้างโดยใช้ Bazel

คุณได้สร้างโดยใช้ Bazel ขณะเพิ่มไฟล์ BUILD เพื่อตรวจสอบการตั้งค่าบิลด์

เมื่อมีไฟล์ BUILD ที่มีความละเอียดตามที่ต้องการแล้ว คุณสามารถใช้ Bazel เพื่อสร้างบิลด์ทั้งหมดได้