i18n Coverage Checker: เทียบไฟล์ Locale หา Key ที่ขาด
เทียบไฟล์ locale JSON สองไฟล์อย่าง en.json vs th.json เพื่อหา missing keys, extra keys และคำแปลว่าง พร้อม coverage ราย namespace — ฟรีในเบราว์เซอร์
Table of Contents
ถ้าคุณเคยดูแลเว็บหรือแอปที่รองรับหลายภาษา คงคุ้นเคยกับความเจ็บปวดของงาน i18n อยู่ข้อหนึ่ง นั่นคือไฟล์ locale คู่ขนานอย่าง en.json กับ th.json มักไม่ตรงกันซะทีเดียว วันหนึ่งทีม dev เพิ่ม key ใหม่ในภาษาอังกฤษ อีกสองวันนักแปลลืมเติมภาษาไทย ผลคือข้อความบนหน้าเว็บโชว์ชื่อ key ตรง ๆ อย่าง checkout.confirm ให้ผู้ใช้อ่าน หรือแย่กว่านั้นคือแสดงข้อความว่างเปล่าโดยไม่มีใครรู้ตัวจนกว่าลูกค้าจะแจ้งเข้ามา
i18n Coverage Checker ถูกออกแบบมาเพื่อจุดนี้โดยเฉพาะ เป็นเครื่องมือฟรี ทำงานใน browser 100% ไม่ต้องสมัครสมาชิกและไม่ต้องติดตั้งอะไร เพียงวางไฟล์ locale JSON สองไฟล์ลงในช่อง เครื่องมือจะเทียบ key ทั้งแบบแบนและแบบซ้อน ชี้ให้เห็น missing keys ทั้งสองทิศทาง extra keys และคำแปลที่ว่าง พร้อมสรุปสถิติ coverage ราย namespace ให้ทันทีในไม่กี่วินาที
บทความนี้จะพาคุณไปเข้าใจว่า coverage ในงานแปลภาษาคำนวณอย่างไร ใช้เครื่องมือนี้ตรวจไฟล์ locale ทีละขั้นตอนเมื่อไหร่ และมีแนวทางปฏิบัติใดที่ช่วยให้ไฟล์ภาษาของทีมไม่หลุดกันอีกต่อไป
ทำไมต้องใช้ i18n Coverage Checker?
- กันข้อความหลุดบนหน้าจอจริง — key ที่ขาดหายหรือยังไม่แปลมักแสดงเป็นชื่อ key ดิบ ๆ หรือข้อความว่างใน UI ซึ่งเป็นความผิดพลาดที่ผู้ใช้เห็นตรง ๆ และทำให้ผลิตภัณฑ์ดูไม่เป็นมืออาชีพทันที
- ตรวจสอบครบสองทิศทางในครั้งเดียว — เครื่องมือแยกบอกให้ชัดว่า key ใดมีในไฟล์ A แต่หายไปจากไฟล์ B และ key ใดที่มีเกินมาในฝั่ง B ช่วยให้ไม่ต้องเปิดไฟล์เทียบกันด้วยตาเปล่าอีกต่อไป
- รองรับทั้ง key แบบแบนและแบบซ้อน — ไม่ว่าไฟล์ของคุณจะใช้ key ระดับเดียวอย่าง common.save หรือซ้อน object หลายชั้น เครื่องมือจะ flatten และเทียบให้ตรงกันทุกระดับ
- จับคำแปลว่างที่มองข้ามยาก — key ที่มีอยู่แต่ค่าเป็นสตริงว่างคือสัญญาณของงานแปลค้าง ซึ่ง diff ทั่วไปมักไม่สะดุดตา แต่เครื่องมือนี้แยกหมวดให้เห็นชัดเจน
- เห็นภาพรวมราย namespace — สถิติ coverage แยกตามกลุ่มโมดูล เช่น checkout หรือ auth พร้อมสถานะระบายสี ครบ 100% เป็นเขียว กลุ่มไหนยังมีปัญหาก็ส่องเจอทันที
- ปลอดภัยและสะดวก — ทุกอย่างประมวลผลใน browser ไฟล์ locale ไม่ถูกส่งไป server ใด ๆ เหมาะกับโค้ดของบริษัทที่มีข้อจำกัดด้านความลับ
ฟีเจอร์หลัก
| ฟีเจอร์ | ทำอะไร |
|---|---|
| วางไฟล์ locale สองไฟล์ | รับเนื้อหา JSON สองชุด เช่น en.json กับ th.json เทียบกันได้ทันทีไม่ต้องตั้งค่า |
| เทียบ key แบบแบนและซ้อน | flatten โครงสร้าง nested ทุกระดับแล้วจับคู่ key ให้ตรงกันอัตโนมัติ |
| Missing keys สองทิศทาง | รายงาน key ที่ขาดในฝั่ง A และ key ที่ขาดในฝั่ง B แยกกันชัดเจน |
| Extra keys | ชี้ key ที่มีเกินมาในไฟล์ใดไฟล์หนึ่ง มักเป็น key เก่าที่ลืมลบหรือตั้งชื่อพิมพ์ผิด |
| ตรวจคำแปลว่าง | หา key ที่มีอยู่แต่ค่าเป็นสตริงว่าง เพื่อยืนยันว่างานแปลครบทุกจุด |
| Coverage ราย namespace | สรุปเปอร์เซ็นต์แยกกลุ่มโมดูล พร้อมสถานะระบายสี ครบ 100% เป็นเขียว เตือนเมื่อยังไม่ครบ |
จุดเด่นที่ควรรู้เพิ่มเติม:
- ผลลัพธ์ออกทันทีใน browser ไม่ต้องกดอัปโหลดหรือรอคิว แก้ไฟล์เมื่อไรวางใหม่ปุ๊บตัวเลขอัปเดตปั๊บ
- การแยก missing / extra / empty ออกจากกันช่วยบอกว่าปัญหาเกิดจากโครงสร้างไฟล์หรือจากเนื้องานแปล ทำให้แก้ถูกจุดตั้งแต่ครั้งแรก
- สถานะระบายสีต่อ namespace ทำให้ทีมสื่อสารกันเร็ว เช่น ตกลงกันว่ากลุ่ม payment ต้องเป็นสีเขียวก่อนขึ้น production เสมอ
วิธีเทียบไฟล์ Locale
- เปิดหน้าเครื่องมือ i18n Coverage Checker
- วางเนื้อหาไฟล์ภาษาอ้างอิง เช่น en.json ลงในช่องแรก โดยไฟล์นี้ควรเป็นเวอร์ชันที่ทีมถือว่าครบที่สุด
- วางไฟล์ที่ต้องการตรวจ เช่น th.json ลงในช่องที่สอง
- อ่านผลลัพธ์ทันที เริ่มจาก missing keys สองทิศทาง extra keys และคำแปลว่าง แล้วค่อยดูตาราง coverage ราย namespace ว่ากลุ่มไหนยังไม่เขียว
- แก้ไฟล์ต้นทางตามรายการที่พบ เช่น เพิ่ม key ที่ขาดหรือเติมค่าที่ว่าง แล้ววางใหม่อีกครั้งเพื่อยืนยันว่าทุก namespace เป็นสีเขียวจริง
Coverage ในงานแปลภาษาหมายความว่าอะไร
งาน i18n สมัยใหม่เก็บข้อความของแต่ละภาษาไว้ในไฟล์ locale ที่มีโครงสร้างเหมือนกันเป๊ะ เรียกว่าไฟล์คู่ขนาน ถ้า en.json มี 320 key แล้ว th.json ก็ต้องมี 320 key เดียวกันทุกตัว ปัญหาคือไฟล์เหล่านี้ถูกแก้โดยคนหลายคนหลายช่วงเวลา ความต่างจึงเกิดขึ้นเสมอ โดยแบ่งเป็นสามสถานการณ์หลัก
Missing key คือ key ที่มีในไฟล์หนึ่งแต่ไม่มีในอีกไฟล์เลย เช่น en.json มี checkout.receipt แต่ th.json ไม่มี เวลาแสดงผลจริง UI จะโชว์ชื่อ key หรือข้อความ fallback ที่ไม่ใช่ภาษาของผู้ใช้ Extra key คือภาพสะท้อนกลับด้าน มีเกินมาในไฟล์หนึ่ง มักเกิดจาก key เก่าที่โค้ดเลิกใช้แล้วแต่ยังลบไม่หมด Empty translation คือกรณีที่เจ็บที่สุด เพราะ key มีอยู่ครบ โครงสร้างถูกต้อง แต่ค่าเป็นสตริงว่าง ผู้ใช้จึงเห็นปุ่มหรือหัวข้อที่ไม่มีตัวอักษรเลย
ตัวอย่างคู่ key ของ en และ th ที่มีทั้งกรณีแปลครบและแปลว่าง:
en.json: { "checkout": { "success": "Payment successful", "error": "Payment failed" } }
th.json: { "checkout": { "success": "ชำระเงินสำเร็จ", "error": "" } }
สังเกตว่า checkout.success สมบูรณ์ แต่ checkout.error มี key อยู่แล้ว เรื่องเดียวที่ขาดคือคำแปล ซึ่งเป็นปัญหาที่การอ่านโค้ดธรรมดามักพลาด
ส่วน namespace คือกลุ่มโมดูลระดับบนของไฟล์ เช่น checkout, auth, common หรือ dashboard ถ้าทีมจัดโครงสร้างดี namespace จะสอดคล้องกับหน้าจอหรือฟีเจอร์ของแอปพอดี ทำให้ตัวเลข coverage ต่อกลุ่มบอกได้ว่าฟีเจอร์ไหนพร้อมใช้งาน ฟีเจอร์ไหนยังแปลไม่เสร็จ
เรื่องคณิตของเปอร์เซ็นต์ coverage ก็ตรงไปตรงมา นับจำนวน key ใน namespace ที่มีคำแปลใช้ได้ หารด้วยจำนวน key อ้างอิงทั้งหมดของ namespace นั้น แล้วคูณ 100 เช่น checkout มี 40 key ฝั่ง en มีครบ ฝั่ง th มี 36 key และในจำนวนนั้น 2 key ค่าว่าง แปลว่า th ใช้ได้จริง 34 key coverage เท่ากับ 34 / 40 × 100 = 85% ซึ่งเครื่องมือจะแสดงเป็นสถานะเตือนทันทีโดยไม่ต้องนับเอง
ทีมที่ทำงานเป็นระบบจะใช้ตัวเลขนี้เป็นเกณฑ์ขั้นต่ำก่อน release เช่น กำหนดว่า namespace ที่เกี่ยวกับการชำระเงินและการสมัครสมาชิกต้อง 100% เพราะกระทบรายได้โดยตรง ส่วนกลุ่ม marketing อาจยอมรับ 95% ได้ชั่วคราว การมีเกณฑ์เขียนไว้ชัดเจนทำให้การตัดสินใจหยุดหรือปล่อยเวอร์ชันไม่ต้องเถียงกันด้วยความรู้สึกอีกต่อไป
กรณีใช้งานจริง
Audit ไฟล์ locale ก่อนออกเวอร์ชันใหม่
สมมติทีมจะปล่อยเวอร์ชัน 2.4 ในวันศุกร์ ระหว่างสปรินต์มีการเพิ่ม key ใหม่ 14 ตัวสำหรับฟีเจอร์ตะกร้าสินค้า เอา en.json กับ th.json มาวางเทียบก่อน tag เวอร์ชัน พบว่า cart.summary.tax_note ยังไม่มีใน th.json และ settings.language ค่าเป็นสตริงว่าง ทีมแก้ทั้งสองจุด เทียบซ้ำจนทุก namespace เขียว แล้วค่อยกดปล่อยอย่างมั่นใจ
เพิ่มภาษาใหม่ให้เว็บแอป
เว็บที่เดิมมี en กับ th ต้องการเพิ่ม ja เข้ามา นักแปลเริ่มจากไฟล์เกือบว่าง วิธีติดตามงานคือเอา en.json เทียบกับ ja.json เป็นระยะ ตัวเลข coverage ราย namespace จะบอกความคืบหน้าชัดเจน เช่น common 100% แล้วแต่ dashboard ยังอยู่ที่ 40% ทีมจึงรู้ว่าควรเปิดภาษาญี่ปุ่นแบบย่อยในส่วนไหนก่อน และควรซ่อนฟีเจอร์ส่วนไหนไว้ชั่วคราวอย่างมีเหตุผลรองรับ
เก็บกวาด key ตาย (dead keys)
หลายโปรเจกต์สะสม extra keys ไว้นานหลายเดือน ลบโค้ดไปแล้วแต่ลืมลบ key รายการ extra keys จากผลเทียบคือรายชื่อตัวเก็บกวาดที่ดีที่สุด ทีมเอารายการนี้ไปค้นในโค้ดเพื่อยืนยันว่าไม่มีที่ไหนอ้างอิงแล้ว จึงลบทิ้งจากทุกไฟล์ภาษาพร้อมกัน ไฟล์เบาลง ขนาด bundle ลดลงนิดหน่อย และผู้ดูแลใหม่ก็ไม่สับสนว่า key ไหนยังใช้งานอยู่จริง
รีวิวงานแปลจากนักแปลหรือ vendor
เมื่อรับไฟล์คืนจากนักแปลอิสระหรือบริษัทรับจ้างแปล อย่าเพิ่ง merge เข้า repo ให้วางเทียบกับไฟล์ภาษาอ้างอิงก่อนทันที เครื่องมือจะชี้ในไม่กี่วินาทีว่าขาด key อะไรไปบ้าง มี key แปลกปลอมเข้ามาหรือเปล่า และมีจุดไหนส่งค่าว่างมา ปัญหาเหล่านี้จับง่ายตอนยังเป็นไฟล์ แต่ยากมากถ้าปล่อยผ่านไปจนขึ้น production แล้วผู้ใช้เป็นคนเจอเอง
แนวทางปฏิบัติที่ดี
- กำหนดภาษาหลักเป็น source of truth เช่น en.json แล้วทุกไฟล์อื่นต้องมี key ตรงกันเสมอ ช่วยลดข้อโต้แย้งว่าไฟล์ไหนถูกต้องกว่ากัน
- เพิ่ม key ทุกภาษาใน PR เดียวกัน อย่าปล่อยให้งานแปลค้างข้ามสปรินต์ เพราะยิ่งปล่อยนานยิ่งลืมง่าย
- ใส่การเทียบ coverage ไว้ใน release checklist เป็นขั้นตอนบังคับควบคู่กับการทดสอบ ใช้เวลาแค่นาทีเดียวแต่ป้องกันความเสียหายทั้งเวอร์ชัน
- ห้ามปล่อยค่าสตริงว่าง ถ้ายังไม่แปลให้เติมข้อความชั่วคราวหรือใช้กลไก fallback ของไลบรารี i18n แทนการเว้นว่างเปล่า
- จัด key เป็น namespace สอดคล้องกับฟีเจอร์ เช่น checkout, auth, settings จะได้รายงาน coverage ที่อ่านรู้เรื่องและมอบหมายงานได้ง่าย
- เทียบซ้ำหลังแก้ทุกครั้ง วางไฟล์ใหม่ในเครื่องมือเพื่อยืนยันว่าเขียวจริง อย่าเชื่อว่าแก้แล้วครบโดยไม่ตรวจอีกรอบ
เครื่องมือนี้ฟรี ใช้ได้ทันทีไม่ต้องสมัครอะไรทั้งสิ้น หากคุณมีไฟล์ locale รอตรวจอยู่แล้ว เปิด i18n Coverage Checker วางสองไฟล์ แล้วไล่ให้ทุก namespace เป็นสีเขียวภายในไม่กี่นาที ความอุ่นใจก่อนขึ้น production ได้ง่ายกว่าที่คิด
เครื่องมือที่เกี่ยวข้องที่คุณอาจสนใจ:
- YAML Diff — เทียบไฟล์ YAML สองไฟล์หาความต่างแบบละเอียด เหมาะกับไฟล์ config และไฟล์แปลที่ใช้รูปแบบ YAML
- Unicode Escape Converter — แปลงข้อความเป็น unicode escape และกลับ เช่น จาก \u0e2a เป็นตัวอักษรไทยจริง มีประโยชน์เวลาจัดการสตริงในไฟล์ locale
- Unicode Lookup — ค้นหาข้อมูลตัวอักษร unicode เมื่อต้องตรวจสอบอักขระพิเศษหรือสัญลักษณ์แปลก ๆ ที่ปนมาในไฟล์แปล
ขอให้แปลภาษาอย่างสนุก!
คำถามที่พบบ่อย
ถ: ไฟล์ locale ของฉันถูกอัปโหลดไปเก็บที่ server หรือไม่?
ตอบ: ไม่ เครื่องมือประมวลผลทั้งหมดใน browser ของคุณ ไฟล์ JSON ไม่ถูกส่งไปที่ใดทั้งสิ้น จึงใช้กับโค้ดที่มีข้อจำกัดด้านความลับของบริษัทได้สบายใจ
ถ: ใช้กับไฟล์ที่ key ซ้อนกันหลายชั้นได้ไหม?
ตอบ: ได้ เครื่องมือเทียบได้ทั้ง key แบบแบนและโครงสร้าง nested ซ้อนหลายระดับ โดยจับคู่เส้นทางของ key ให้ตรงกันก่อนสรุปผล
ถ: ควรตั้งเป้า coverage เท่าไรก่อน release?
ตอบ: แนะนำ 100% สำหรับ namespace ที่กระทบการใช้งานหลักหรือรายได้ เช่น checkout และ auth ส่วนกลุ่มอื่นอาจยอมรับที่ 95% ได้ชั่วคราว ขึ้นอยู่กับนโยบายของทีม
ถ: เทียบได้มากกว่าสองไฟล์พร้อมกันไหม?
ตอบ: เครื่องมือเทียบทีละคู่ ถ้ามีหลายภาษาให้เทียบไฟล์อ้างอิงกับภาษาละไฟล์ เช่น en vs th ก่อน แล้วค่อย en vs ja
ถ: ต้องสมัครสมาชิกหรือติดตั้งอะไรก่อนใช้งานหรือไม่?
ตอบ: ไม่ต้องเลย เป็นเครื่องมือฟรี ทำงานใน browser ทันที เปิดหน้าเว็บแล้ววางไฟล์ได้เลย