เราเลิกคิดว่าจะรอ Linter ที่สมบูรณ์แบบ: การย้ายไป ESLint V9 และการนำ Biome แบบไฮบริดมาใช้
(blog.lemonbase.team)แบ่งปันประสบการณ์ของ Frontend Chapter ที่ Lemonbase ซึ่งย้ายไปใช้ ESLint V9 เพื่อรับมือกับการสิ้นสุดการรองรับ ESLint V8 และแก้ปัญหาด้านประสิทธิภาพด้วยการนำ Biome แบบไฮบริดมาใช้
ที่มาของการนำมาใช้
- กันยายน 2024 มีประกาศยุติการรองรับ ESLint V8 ทำให้การย้ายไป V9 เป็นสิ่งจำเป็นหากต้องการรับ security patch และ bug fix
- ตั้งแต่ V9 การตั้งค่าบนพื้นฐาน
.eslintrc.jsถูก deprecated และ Flat Config กลายเป็นค่าเริ่มต้น - มีการใช้งานกฎประมาณ 400 รายการ, โครงสร้างไฟล์ตั้งค่าแบบแยกสองส่วน, และจำเป็นต้องตรวจสอบความเข้ากันได้ของปลั๊กอินหลายตัว
กระบวนการย้าย
- เครื่องมือ migration อย่างเป็นทางการของ ESLint ทำได้เพียงห่อด้วย
@eslint/compatจึงไม่เป็นไปตามที่คาดหวัง - ใช้เครื่องมือ AI สร้างร่างแรก แต่เกิดปัญหากฎที่ตกหล่นและปัญหาความเข้ากันได้จำนวนมาก
- สุดท้ายจึงใช้สเปรดชีตเทียบกฎของ V8/V9 ทีละบรรทัดและตรวจสอบทั้งหมด
ปัญหาด้านประสิทธิภาพหลังย้าย
- หลังอัปเกรดเป็น V9 กลับช้าลงอีก 30 วินาที จาก 154 วินาที → 184 วินาที
- กฎ
import/no-cycleช้ากว่า V8 ถึง 10 เท่า และกินสัดส่วน 45.8% ของทั้งหมด - กฎ
prettier/prettierก็คิดเป็น 10.2% โดยมี overhead จากการ parse ซ้ำเป็นคอขวด
การนำ Biome แบบไฮบริดมาใช้
- เปลี่ยนจากแนวทางแทนที่ทั้งหมด มาเป็นแนวทาง "ใช้ร่วมกันแล้วโฟกัสที่ประโยชน์"
- เปลี่ยนจาก Prettier → Biome Formatter ทำให้เวลา formatting ลดจาก 14 วินาที → 2 วินาที
- ให้ ESLint รับผิดชอบเฉพาะ custom rule ของโปรเจกต์
ผลลัพธ์สุดท้าย
- ESLint V8: 154 วินาที → ESLint V9: 184 วินาที
- ESLint Only → ไฮบริด Biome + ESLint: ~20 วินาที
สิ่งที่ได้เรียนรู้
- หากจะให้ AI ช่วยทำ migration ควรให้วางแผนก่อนแล้วให้คนตรวจทาน พร้อมกำหนดเกณฑ์ความสำเร็จให้ชัดเจน (เช่น ผลลัพธ์ต้องตรงกับ V8)
- แทนที่จะรอเครื่องมือที่สมบูรณ์แบบ บางครั้งการผสมเครื่องมือที่ใช้ได้ตอนนี้ให้เหมาะสม อาจเป็นทางลัดที่เร็วกว่า
ข้อควรระวัง
- เมื่อใช้สองเครื่องมือร่วมกัน ต้องดูแลทั้ง
eslint.config.mjsและbiome.jsonและอาจเกิดความขัดแย้งของกฎได้ - ควรกำหนดให้ชัดว่าแต่ละกฎอยู่ในความรับผิดชอบของเครื่องมือใด และต้องอธิบายการแบ่งบทบาทนี้ตอน onboarding สมาชิกใหม่
2 ความคิดเห็น
ดูเหมือนจะเป็นบทความที่ให้มุมมองที่ดีสำหรับคนที่ยังเจอปัญหาเรื่องประสิทธิภาพของ lint อยู่
ฝั่งเราก็มีประสบการณ์คล้ายกันเมื่อปีที่แล้ว ตอนปรับปรุงให้ใช้งาน oxc(oxlint) และ ESLint แบบไฮบริด ทำให้ลดเวลาการ lint จากที่เคยใช้เกิน 200 วินาที เหลือไม่ถึง 15 วินาทีได้
ตอนแรกผมเองก็ลองย้ายแบบดื้อ ๆ ด้วย AI แต่พอมี rules ที่ตกหล่นหรือเพี้ยนเกิดขึ้นเรื่อย ๆ ก็เลยลังเลว่าจะต้องมานั่งไล่ตรวจทีละข้อไหม
สุดท้ายเลยให้ AI ช่วยเขียนสคริปต์สำหรับดึง rules ที่ oxc รองรับออกมา แล้วปรับให้เปิดใช้งานเฉพาะ rules ที่ oxc ยังไม่รองรับผ่าน ESLint เท่านั้น พอทำแบบนี้แล้ว ตอนนี้ก็อัปเดต rules ที่รองรับเพิ่มใหม่เป็นระยะ ๆ ได้ง่ายขึ้นมาก...
ช่วงแรกกระบวนการข้างต้นยังเป็นแบบกึ่งอัตโนมัติ แต่ตอนนี้นิยามเป็น Skill ไว้แล้ว แค่สั่งรันด้วย Claude Code ก็พอ เลยทำให้ภาระลดลงไปเยอะ ซึ่งก็ดีมากครับ
ไม่ลองใช้ oxlint กับ oxfmt แทน eslint กับ prettier ดูเหรอครับ?
ในขณะที่ config รองรับแบบ 1:1 ความเร็วจะเพิ่มขึ้นอย่างน้อยหลายสิบเท่า