พัฒนา formatter สำหรับ C, C++, Java และ JavaScript ด้วย Clang ในสภาพแวดล้อม Node.js
(github.com/lumirlumir)- GitHub repository: https://github.com/lumirlumir/npm-clang-format-node
- เว็บไซต์เอกสารอย่างเป็นทางการ: https://clang-format-node.lumir.page/
สวัสดีครับ!
ผมได้พัฒนา formatter สำหรับ C, C++, Java และ JavaScript ที่ใช้ Clang ในสภาพแวดล้อม Node.js โปรเจ็กต์นี้เป็นโปรเจ็กต์ใหม่ที่เริ่มต้นขึ้นบนพื้นฐานของแพ็กเกจ clang-format ของ Angular ที่ไม่ได้รับการดูแลต่อแล้ว
เมื่อสองสามเดือนก่อนผมเคยแชร์เนื้อหาในลักษณะคล้ายกันไปแล้ว และครั้งนี้ได้ปล่อยเวอร์ชัน v1.3.0 พร้อมเพิ่มเว็บไซต์เอกสารแบบละเอียดเพื่อให้ผู้ใช้สามารถใช้งานได้ง่ายและสะดวกยิ่งขึ้น เว็บไซต์เอกสารสามารถดูได้ที่นี่ โดยมีตั้งแต่วิธีติดตั้งพื้นฐานไปจนถึงเหตุผลว่าทำไมจึงควรใช้แพ็กเกจนี้ หากสนใจก็ลองเข้าไปอ่านกันได้ครับ
ในการอัปเดตครั้งนี้ ได้เพิ่มการทดสอบหลายรายการเพื่อยกระดับความเสถียรของแพ็กเกจให้มากขึ้น และยังมีการเพิ่มฟีเจอร์ใหม่ ๆ เข้ามาด้วย
แพ็กเกจทั้งหมดนี้ใช้สัญญาอนุญาต MIT และสามารถนำไปใช้งานได้อย่างอิสระ
clang-format-node คือโปรเจ็กต์แบบไหน?
แพ็กเกจนี้เป็นแพ็กเกจ Node.js ที่รองรับการจัดรูปแบบโค้ดสำหรับภาษา C, C++, Java โดยอิงจาก clang-format ของ Clang ซึ่งเป็นที่รู้จักกันดีในฐานะคอมไพเลอร์ C ของ LLVM กล่าวอย่างง่ายคือ มันทำหน้าที่คล้ายกับ Prettier ในสภาพแวดล้อม Node.js แต่จุดที่ต่างคือรองรับการจัดรูปแบบภาษา C, C++ และ Java ซึ่ง Prettier ไม่รองรับ
โดยเฉพาะในกรณีที่ต้องเขียนโค้ด JavaScript และโค้ด C/C++ ควบคู่กัน เช่น การพัฒนา Node.js core หรือ Electron นั้น clang-format-node จะมีประโยชน์มาก
แพ็กเกจ clang-format แบบเดิมมีความยุ่งยากตรงที่ต้องติดตั้ง dependency เพิ่มเติมซึ่งอิงกับสภาพแวดล้อมของระบบปฏิบัติการอย่าง Ubuntu เป็นต้น แต่เมื่อใช้แพ็กเกจนี้จะสามารถใช้งานได้ทันทีโดยไม่ต้องติดตั้งอะไรเพิ่มเติม นอกจากนี้ ในขณะที่แพ็กเกจเดิมค่อนข้างรวมเข้ากับ workflow แบบ Node.js และ npm ในสภาพแวดล้อม CI ได้ยาก clang-format-node สามารถใช้งานได้อย่างสะดวกใน CI เพียงติดตั้งจาก npm และตั้งค่าสคริปต์เท่านั้น
ถ้าอย่างนั้น จุดเด่นของแพ็กเกจ clang-format-node คืออะไร?
1. Drop-in Replacement สำหรับแทนที่ clang-format ของ Angular
clang-format-node เป็น Drop-in Replacement ที่สามารถแทนที่แพ็กเกจ Angular/clang-format ได้อย่างง่ายดาย
การเปลี่ยนจากแพ็กเกจเดิมมาเป็น clang-format-node ทำได้ง่ายมาก และสามารถเริ่มใช้งานได้ทันทีโดยแทบไม่ต้องมีขั้นตอนซับซ้อน
2. ใช้แค่ Node.js ก็พอ โดยไม่ต้องมี dependency เพิ่มเติมเพื่อใช้ Clang
ไม่จำเป็นต้องมี dependency เพิ่มเติมอย่าง Python หรือ C++ เลย เพียงมี Node.js ก็สามารถรันได้ง่าย ๆ
3. รองรับได้อย่างกว้างขวาง
รองรับระบบปฏิบัติการและสถาปัตยกรรมที่หลากหลาย เวอร์ชันของ Node.js, runner image ของ GitHub Actions และ Docker build image อย่างครอบคลุม
4. ตั้งค่า CI ได้ง่าย
สามารถใช้ clang-format-node ได้เหมือนกับแพ็กเกจ Node.js อื่น ๆ โดยไม่ต้องตั้งค่าซับซ้อน
5. ระบบ build และ release อัตโนมัติ
ทุกครั้งที่มีการอัปเดต clang-format จะมีการปล่อย npm เวอร์ชันใหม่โดยอัตโนมัติ GitHub Actions จะตรวจจับการอัปเดตเป็นระยะ สร้างแพ็กเกจ และเปิด Pull Request ให้โดยอัตโนมัติ
จัดรูปแบบโค้ดด้วย clang-format และ git-clang-format
(ข้อความด้านล่างนี้คือเนื้อหาบางส่วนที่ผมเขียนเป็นภาษาอังกฤษไว้ในส่วน https://clang-format-node.lumir.page/docs/get-started/introduction แล้วแปลเป็นเกาหลีบางส่วน)
ความสำคัญของการจัดรูปแบบโค้ด
จัดรูปแบบโค้ดอยู่เสมอ
การจัดรูปแบบโค้ดเป็นงานที่สำคัญมากในการยกระดับคุณภาพของโค้ด หัวใจสำคัญของการจัดรูปแบบคือการรักษาความสม่ำเสมอของรูปแบบโค้ด เพื่อเพิ่มความอ่านง่ายและความเข้าใจได้ง่าย
clang-format คืออะไร?
clang-format เป็นเครื่องมือสำหรับจัดรูปแบบไฟล์ซอร์สของภาษาอย่าง C และ C++ โดยอัตโนมัติ และถูกพัฒนาขึ้นเป็นส่วนหนึ่งของโครงการโอเพนซอร์ส LLVM Clang
วิธีการทำงาน
- สร้างไฟล์ตั้งค่า
สร้างไฟล์ตั้งค่า (.clang-format) ที่กำหนดรูปแบบการจัดฟอร์แมต - รันคำสั่ง
เมื่อรันคำสั่งclang-formatซอร์สโค้ดจะถูกจัดโครงสร้างใหม่โดยอัตโนมัติตามกฎของรูปแบบที่กำหนด
คุณสมบัติหลัก
- รองรับหลายภาษา
รองรับภาษาหลากหลาย เช่น C, C++, Java, JavaScript, Objective-C, Protobuf, C# เป็นต้น - ตัวอย่างคำสั่งจัดรูปแบบ
เมื่อรันคำสั่งข้างต้น ไฟล์clang-format -i my_source.cppmy_source.cppจะถูกจัดรูปแบบอัตโนมัติตามสไตล์ที่กำหนด
ตัวอย่างการจัดรูปแบบโค้ด
// Before formatting
void test(QString&data, bool extraString) {
int i=0;
for (i=0;i<3;i++) {
data+="reallylongstringtoproducealonglineasanexample" + QString::number(i * 1000) + "/filetoload.html";
if (extraString)
{
data += "some-extra";
}
}
}
// After formatting
void test(QString &data, bool extraString)
{
int i = 0;
for (i = 0; i < 3; i++) {
data += "reallylongstringtoproducealonglineasanexample" + QString::number(i * 1000)
+ "/filetoload.html";
if (extraString) {
data += "some-extra";
}
}
}
ตัวอย่างข้างต้นแสดงให้เห็นว่า clang-format จัดรูปแบบโค้ดอย่างไร โดยสามารถตั้งกฎการจัดรูปแบบให้เหมาะกับสไตล์ของทีมได้อย่างอิสระ
ปัญหาของ clang-format
clang-format เป็นเครื่องมือที่ยอดเยี่ยม แต่ก็อาจก่อให้เกิดปัญหากับ โค้ดเดิม และ ประวัติการคอมมิต ได้
ปัญหาหลัก
- ขัดแย้งกับโค้ดเดิม
หากจัดรูปแบบทั้งไฟล์ ส่วนที่ไม่เกี่ยวกับการจัดรูปแบบก็อาจถูกเปลี่ยนไปด้วย ทำให้เกิดการเปลี่ยนแปลงที่ไม่จำเป็น - ทำให้ประวัติการคอมมิตสับสน
การเปลี่ยนแปลงการจัดรูปแบบขนาดใหญ่ทำให้ประวัติการคอมมิตซับซ้อนขึ้น และอาจสร้างความยากลำบากในการรวมสาขา การรีวิวโค้ด และการวิเคราะห์โค้ด - ความไม่สอดคล้องระหว่างโค้ดใหม่กับโค้ดเดิม
เมื่อเพิ่มโค้ดใหม่ลงในโค้ดที่ถูกจัดรูปแบบไว้แล้ว การรักษารูปแบบเดิมอาจทำได้ยาก
ทางออก: git-clang-format
git-clang-format เป็น Git extension ที่ช่วยให้สามารถจัดรูปแบบเฉพาะโค้ดที่มีการเปลี่ยนแปลงได้ ซึ่งมีข้อดีดังนี้
- ลดขอบเขตของการจัดรูปแบบให้น้อยที่สุด: จัดรูปแบบเฉพาะโค้ดที่เปลี่ยนแปลง
- ทำให้การรีวง่ายขึ้น: สามารถตรวจแยกการเปลี่ยนแปลงด้านการจัดรูปแบบกับการพัฒนาออกจากกันได้
วิธีใช้ git-clang-format
การติดตั้ง
git-clang-format มาพร้อมกับแพ็กเกจ clang-format-node และสามารถติดตั้งใช้งานผ่านแพ็กเกจ npm clang-format-git ได้
เวิร์กโฟลว์พื้นฐาน
- เขียนโค้ด
- เพิ่มการเปลี่ยนแปลงเข้า staging (
git add) - รัน
git-clang-format
ตัวอย่าง
# เพิ่มไฟล์ใหม่และสเตจการเปลี่ยนแปลง
$ git diff --staged
diff --git a/x.cpp b/x.cpp
new file mode 100644
index 0000000..af14ed5
--- /dev/null
+++ b/x.cpp
@@ -0,0 +1,3 @@
+int main() {
+
+}
# รัน git-clang-format
$ git-clang-format
changed files:
x.cpp
# ตรวจสอบสถานะหลังจัดรูปแบบ
$ git status
On branch master
Changes to be committed:
new file: x.cpp
Changes not staged for commit:
modified: x.cpp
เวิร์กโฟลว์นี้ช่วยให้สามารถตรวจสอบการเปลี่ยนแปลงด้านการจัดรูปแบบและการพัฒนาได้อย่างเป็นอิสระ หากไม่ชอบผลลัพธ์การจัดรูปแบบก็สามารถย้อนกลับได้ด้วย git checkout
การกำหนดสไตล์
สามารถกำหนดสไตล์การจัดรูปแบบได้ด้วยตัวเลือก --style
$ git-clang-format --style=WebKit
$ git-clang-format --style=file # ใช้ไฟล์ `.clang-format`
สรุป
clang-format เป็นเครื่องมือที่ทรงพลัง แต่ในงานจริง หลายครั้งคำสั่ง clang-format -i เพียงอย่างเดียวอาจไม่เพียงพอ หากใช้ git-clang-format เพื่อจัดรูปแบบเฉพาะส่วนที่เปลี่ยนแปลง ก็จะช่วยให้จัดการโค้ดได้อย่างมีประสิทธิภาพและทำให้กระบวนการรีวง่ายขึ้น
เนื่องจาก git-clang-format จะจัดรูปแบบเฉพาะส่วนที่มีการเปลี่ยนแปลง จึงช่วยรักษา codebase ให้สะอาดและเป็นมืออาชีพ พร้อมทั้งยังคงความยืดหยุ่นของสภาพแวดล้อมการพัฒนาไว้ได้ เมื่อต้องจัดรูปแบบคอมมิตการทำงานหรือทั้งสาขา ก็เพียงใช้คำสั่ง Git เพิ่มอีกไม่กี่คำสั่ง ก็สามารถแก้ปัญหาการจัดรูปแบบได้อย่างง่ายดาย
ขอบคุณที่อ่านมาจนจบครับ! ขอให้ผู้อ่าน GeekNews ทุกท่านมีความสุขในวันปีใหม่🙇♂️
- GitHub repository: https://github.com/lumirlumir/npm-clang-format-node
- เว็บไซต์เอกสารอย่างเป็นทางการ: https://clang-format-node.lumir.page/
2 ความคิดเห็น
ขอกดไลก์ให้แล้วกัน
ขอบคุณครับ!!