วิธีการทำงานของ JavaScript beautification
Beautifier อ่านโค้ดทีละตัวอักษร ติดตามความลึกของการซ้อน (nesting) ของแต่ละ statement แล้ว re-emit ออกมาพร้อมการเว้นระยะที่สม่ำเสมอ โดยไม่เปลี่ยนพฤติกรรมของโค้ดเลย — เปลี่ยนแค่หน้าตา
- Tokenize. ไลบรารีสแกน input เป็น token stream: keyword, identifier, string, operator และ punctuation โดย string literal, template literal และ regular-expression literal ถูกมองเป็นหน่วยเดียว ทำให้วงเล็บปีกกาใน string ไม่ถูกเข้าใจผิดว่าเป็น block delimiter
- ติดตาม nesting. ขณะเดิน token stream beautifier จะรักษา indent level แบบ real-time วงเล็บปีกกา วงเล็บเหลี่ยม และวงเล็บกลมที่เปิดจะทำให้ level ลึกขึ้น ส่วนที่ปิดจะดึง level กลับ ความลึกนี้กำหนดจำนวน indent unit ที่วางหน้าแต่ละบรรทัดในผลลัพธ์
- ใช้ตัวเลือกที่ตั้งไว้. ตัวเลือกการย่อหน้า (2 ช่องว่าง, 4 ช่องว่าง หรือ tab) กำหนดความกว้างของหนึ่ง level การตั้งค่าสไตล์วงเล็บปีกกาตัดสินว่าวงเล็บปีกกาเปิดจะอยู่บรรทัดเดียวกับ statement ที่นำหน้า หรือจะขึ้นบรรทัดใหม่เอง ส่วน cap ของบรรทัดว่างจะยุบบรรทัดว่างหลายๆ บรรทัดลงเหลือตามจำนวนที่กำหนด
- Re-emit. สุดท้าย formatter พิมพ์ token กลับออกมาพร้อม indentation และ line break ที่คำนวณไว้ พร้อมเพิ่ม semicolon ที่ automatic semicolon insertion จะเติมให้ตอน runtime ได้ ผลลัพธ์คือโปรแกรมเดิมในรูปแบบที่มนุษย์อ่านได้
ทำไมต้องจัดรูปแบบ JavaScript
- อ่านโค้ดที่ถูกบีบอัด. Production bundle ส่งมาเป็นบรรทัดเดียวพร้อมชื่อตัวแปรตัวอักษรเดียว การ beautify ช่วยคืนการขึ้นบรรทัดและการย่อหน้า ทำให้สามารถตามรอย bug ถึง statement ที่เป็นต้นเหตุได้จริง แม้ไม่มี source map
- จัดการไฟล์ที่มี style ไม่สม่ำเสมอ. โค้ดที่หลายคนแตะมักมีการย่อหน้าและสไตล์วงเล็บปีกกาที่ปะปน ผ่าน beautifier ครั้งเดียวก็ normalize ทั้งไฟล์ให้เป็น layout เดียวกัน ทำให้ diff ถัดไปแสดงการเปลี่ยนแปลงเชิงตรรกะจริงๆ แทนที่จะเป็น whitespace noise
- เครื่องมือนี้ไม่ทำให้หน้าช้าลง. formatter ออนไลน์ส่วนใหญ่โหลดไลบรารีทั้งหมดทันทีที่เปิดหน้า เครื่องมือนี้ lazy-load js-beautify เฉพาะเมื่อคุณคลิก Beautify หรือเปิดโหมดสด การเปิดหน้าจึงใช้เพียงไม่กี่กิโลไบต์แทนที่จะเป็นหลายร้อย และการ render เริ่มต้นยังคงเร็ว
- โค้ดไม่ออกจากเบราว์เซอร์. Beautifier ทำงานบนอุปกรณ์ของคุณทั้งหมด โค้ดของคุณไม่ถูกอัปโหลดขึ้น server เลย ซึ่งสำคัญมากเมื่อ script ที่กำลังตรวจสอบเป็นของลูกค้า มี internal API path หรืออยู่ภายใต้ข้อตกลงการรักษาความลับ
การใช้งานทั่วไป
JavaScript beautification เกิดขึ้นทุกครั้งที่ต้องอ่านโค้ดที่ไม่ได้ถูกเขียนมาเพื่อให้อ่าน
- Debug production: วาง minified bundle จาก Network tab เพื่อหา function ที่อยู่เบื้องหลัง error stack ที่แกะไม่ออก
- เตรียม code review: reformat ไฟล์ของ contributor ที่ indentation ไม่สม่ำเสมอก่อนเปิด pull request เพื่อให้ reviewer เห็น logic ไม่ใช่ layout
- ตรวจสอบด้านความปลอดภัยและการปฏิบัติตามกฎระเบียบ: ขยาย script analytics หรือ ad snippet ของ third party เพื่อยืนยันพฤติกรรมที่แท้จริงก่อนนำไปใช้งาน
ตัวอย่างที่ใช้งานได้จริง
ลองใช้ one-liner ที่บีบอัดแล้ว: function f(a){if(a){return a*2}else{return 0}} วางด้านบนโดยตั้ง indentation เป็น 2 ช่องว่างและ brace style เป็น Collapse แล้วคลิก Beautify คุณจะได้ block ที่อ่านได้: function f(a) { ตามด้วย if (a) { ที่ indent แล้ว, statement return a * 2; ที่ลึกลงอีกหนึ่ง level และวงเล็บปีกกาที่เรียงกันด้านล่าง เปลี่ยน brace style เป็น Expand แล้ววงเล็บปีกกาเปิดทุกตัวจะขึ้นบรรทัดใหม่ เปลี่ยน indentation เป็น Tab แล้วแต่ละ level จะใช้ tab character แทนสองช่องว่าง โครงสร้างเหมือนเดิมทุกประการ เปลี่ยนแค่ layout
FAQ
รันในเบราว์เซอร์ของฉันหรือไม่?
ใช่ ไลบรารี js-beautify โหลดแบบ lazy ครั้งแรกที่คุณคลิก Beautify หรือเปิดโหมดสด แล้ว cache ไว้ โค้ดของคุณจะไม่ออกจากหน้าเลย ไม่มีการส่งข้อมูลไป server และไม่มีการอัปโหลด
การ beautify เหมือนกับ un-minify หรือไม่?
มันคืน formatting ที่อ่านได้ — indentation, line break และ spacing — แต่ไม่สามารถนำชื่อตัวแปรต้นฉบับหรือ comment ที่ถูก minification ลบออกไปคืนมาได้ ถ้ามี source map เบราว์เซอร์ DevTools จะช่วยกู้ชื่อต้นฉบับได้ beatuifier เองทำงานได้เฉพาะกับสิ่งที่อยู่ในไฟล์เท่านั้น
การ beautify จะเปลี่ยนพฤติกรรมโค้ดไหม?
ไม่ Beautification เพิ่มและลบแค่ whitespace และ line break เท่านั้น โปรแกรมทำงานเหมือนเดิมทุกประการ ตัวเลือกเดียวที่แตะ token คือ "เพิ่ม semicolon ที่หายไป" ซึ่งใส่ statement terminator ที่ ASI จะเพิ่มให้ตอน runtime อยู่แล้ว ทำให้โค้ดปลอดภัยสำหรับการ minify ในภายหลัง
ตัวเลือก brace style หมายความว่าอย่างไร?
Collapse เก็บวงเล็บปีกกาเปิดไว้บรรทัดเดียวกับ statement (if (x) {) ซึ่งเป็น JavaScript convention ทั่วไป Expand วางวงเล็บปีกกาเปิดทุกตัวในบรรทัดของตัวเอง (Allman style) ส่วน End-expand เก็บวงเล็บปีกกาเปิดติดกับ statement แต่วาง else และ catch ในบรรทัดใหม่หลังวงเล็บปีกกาปิด
JavaScript beautification ฝั่งเบราว์เซอร์ให้โค้ดที่อ่านได้โดยไม่ต้องมี build step หรืออัปโหลด วาง script ที่ถูกบีบอัดหรือรก เลือก indentation และ brace style แล้วคัดลอกหรือดาวน์โหลดผลลัพธ์ โค้ดไม่ออกจากอุปกรณ์ของคุณ ไม่ต้องมีบัญชี และไลบรารีโหลดเฉพาะเมื่อคุณขอเท่านั้น การเปิดหน้านี้จึงสิ้นเปลืองเพียงไม่กี่กิโลไบต์ ไม่ใช่เมกะไบต์