- Meta กำลังเปลี่ยนโค้ดเบส Android จาก Java ไปเป็น Kotlin ผ่านโครงการที่ดำเนินมาหลายปี
- ปัจจุบันดูแลหนึ่งในโค้ดเบส Android ที่ใหญ่ที่สุดในโลก และแปลงเป็น Kotlin สำเร็จแล้วมากกว่าครึ่ง
- Meta ใช้กลยุทธ์การพัฒนาแบบ Kotlin-first มาตั้งแต่ปี 2020
- เหตุผลที่แปลงโค้ดทั้งหมด:
- เพื่อใช้ประโยชน์จากข้อดีของ Kotlin ในด้าน "เพิ่มประสิทธิภาพการพัฒนา" และ "ความปลอดภัยของ Null" ให้ได้สูงสุด จึงตัดสินใจแปลงแม้กระทั่งโค้ด Java เดิมที่มีขนาดหลายสิบล้านบรรทัด
- เสริมความแข็งแกร่งด้านความปลอดภัยของ Null และแก้ปัญหาจากโค้ดเบสแบบผสม
- การคอมไพล์แบบผสม (คอมไพล์ Java และ Kotlin พร้อมกัน) ทำให้ความเร็วในการบิลด์ช้าที่สุด
- โค้ด Java ที่ยังเหลืออยู่ก่อให้เกิดปัญหาด้านความปลอดภัยของ Null: โค้ด Java ที่ไม่ปลอดภัยต่อ Null อาจเป็นสาเหตุของ
NullPointerException (NPE) ในกราฟการพึ่งพา
- Kotlin รับประกันความปลอดภัยของ Null ผ่านการตรวจสอบขณะรันไทม์
กระบวนการอัตโนมัติ
- ในช่วงแรกใช้เครื่องมือแปลง J2K ของ Intellij IDE แบบทำซ้ำหลายรอบ
- สำหรับโค้ดเบสขนาดใหญ่ของ Meta ต้อง คลิกมากกว่า 100,000 ครั้ง และแต่ละครั้งใช้เวลาหลายนาที
- สุดท้ายวิธีนี้จึงไม่มีประสิทธิภาพเพราะ ขยายสเกลไม่ได้
- ได้พัฒนา เครื่องมืออัตโนมัติ: Kotlinator ขึ้นมา
- กระบวนการแปลง 6 ขั้นตอน
- Deep Build: บิลด์โค้ดที่จะถูกแปลง เพื่อให้ IDE สามารถ resolve สัญลักษณ์ทั้งหมดได้ รวมถึง dependency ของบุคคลที่สามและโค้ดที่ถูก generate
- Preprocessing: ใช้เครื่องมือเฉพาะของ Meta ที่ชื่อ Editus เป็นพื้นฐาน มีราว 50 ขั้นตอน เช่น การจัดการความปลอดภัยของ Null, dependency และการทำ workaround ให้ J2K
- Headless J2K: ปรับ J2K ให้สามารถรันในสภาพแวดล้อมเซิร์ฟเวอร์ได้
- Postprocessing: มีราว 150 ขั้นตอน เช่น การเปลี่ยนแปลงเฉพาะ Android, ความปลอดภัยของ Null และการปรับให้เป็นสไตล์ Kotlin
- Linters: ปรับปรุงคุณภาพการแปลงอย่างต่อเนื่องผ่านการแก้ไขอัตโนมัติ
- Build Error-based Fixes: วิเคราะห์ build error แล้วนำไปสู่การแก้ไขเพิ่มเติม
การทำให้ J2K ทำงานแบบเฮดเลส
- ปรับ J2K ให้สามารถรันจากระยะไกลได้:
- J2K ผูกติดกับ Intellij IDE อย่างแน่นแฟ้น จึงยากต่อการรันแบบแยกอิสระ
- ตอนแรกพิจารณาการรันผ่านสภาพแวดล้อมทดสอบของ Intellij แต่หลังหารือกับผู้เชี่ยวชาญ J2K ของ JetBrains (Ilya Kirillov) ก็เปลี่ยนมาใช้ แนวทาง headless inspection
- สร้างปลั๊กอิน Intellij โดยขยายคลาส
ApplicationStarter และเรียกใช้คลาส JavaToKotlinConverter ของ J2K เพื่อทำงานนี้
- ข้อดีของแนวทางแบบเฮดเลส
- แก้ปัญหา IDE ฝั่งโลคัล: นักพัฒนาไม่ต้องคลิกปุ่มใน IDE ด้วยตนเอง
- แปลงหลายไฟล์พร้อมกัน: จัดการไฟล์จำนวนมากได้
- ลดเวลาที่ใช้: แม้เวลาแปลงจริงจะเพิ่มเป็นราว 30 นาที แต่เวลาที่นักพัฒนาต้องเสียไปลดลงมาก
- รองรับการบิลด์และการแก้ error: ขั้นตอนที่ใช้เวลามากแต่มีประโยชน์ (การแก้หลังบิลด์) สามารถรันอัตโนมัติจากระยะไกลได้
- ระบบอัตโนมัติและการรีวิวโค้ด
- ใช้ระบบภายในของ Meta เพื่อสร้าง งานแบตช์รายวัน:
- สร้าง diffs แบบแบตช์ตามเกณฑ์ที่กำหนดเอง (เวอร์ชัน pull request ของ Meta)
- จัดสรรผู้รีวิวโดยอัตโนมัติ พร้อมรันทดสอบและตรวจสอบ ก่อนนำ diff ที่ได้รับอนุมัติไป deploy ในที่สุด
- มีเว็บ UI ให้ใช้: นักพัฒนาสามารถสั่งแปลงไฟล์หรือโมดูลที่ต้องการจากระยะไกลได้
- การกำหนดลำดับการแปลง
- ไม่ได้บังคับลำดับตายตัว:
- ให้ความสำคัญกับ ไฟล์ที่มีการพัฒนาอยู่เป็นอันดับแรก
- Kotlinator จัดการกราฟการพึ่งพาโดยอัตโนมัติ เพื่อแก้ปัญหาความเข้ากันได้ของไฟล์ภายนอก
- ตัวอย่าง: อัปเดต
foo.getName() เป็น foo.name อัตโนมัติ
อื่น ๆ
- เพิ่มขั้นตอน Preprocessing แบบกำหนดเอง (Java->Java) และ Postprocessing (Kotlin->Kotlin)
- ใช้เครื่องมือภายในของ Meta อย่าง Editus และไลบรารี JetBrains PSI เพื่อยกระดับคุณภาพการแปลง
- Nullsafe และ NullAway
สถานะปัจจุบันและอนาคตของการแปลงเป็น Kotlin
- โค้ด Android Java ของ Meta มากกว่าครึ่งถูกแปลงเป็น Kotlin แล้ว (หรือบางส่วนถูกลบออกไปแล้ว)
- แต่ ครึ่งที่ง่ายได้จบไปแล้ว:
- งานที่เหลือมีความซับซ้อนและขนาดใหญ่
- สำหรับการแปลงที่ อัตโนมัติได้ทั้งหมด จำเป็นต้องเพิ่มขั้นตอนเฉพาะทางหรือมีส่วนช่วยปรับปรุง J2K
- สำหรับ การแปลงแบบกึ่งอัตโนมัติ เป้าหมายคือทำให้ Kotlinator ดีขึ้นเพื่อให้การ deploy ราบรื่นและปลอดภัย
- Meta มองว่าบริษัทอื่น ๆ ก็น่าจะเผชิญปัญหาคล้ายกันในการแปลงโค้ด Android
- Meta แบ่งปันแนวทางแก้ปัญหาที่ได้จากการปรับปรุงและเพิ่มประสิทธิภาพเครื่องมือแปลง
- ข้อเสนอเพื่อความร่วมมือ:
ยังไม่มีความคิดเห็น