Frontend Fundamentals
(frontend-fundamentals.com)มีการเผยแพร่เว็บไซต์ที่แนะนำเกณฑ์ของโค้ดฟรอนต์เอนด์ที่ดีตามมุมมองของทีม Frontend Chapter ของ Toss
- อธิบายโดยอิงกับ TypeScript ที่นักพัฒนาฟรอนต์เอนด์ใช้งานเป็นหลัก
- นำเสนอ best practice จาก 4 มุมมอง ได้แก่ ความอ่านง่าย/ความคาดเดาได้/ความสอดคล้องภายใน/การพึ่งพากัน
- มีตัวอย่างการใช้งานไลบรารีที่ใช้กันบ่อยในงานฟรอนต์เอนด์จริง
4 เกณฑ์
-
ความอ่านง่าย
ความอ่านง่าย (Readability) คือระดับที่โค้ดอ่านและทำความเข้าใจได้ง่าย หากต้องการให้โค้ดแก้ไขได้ง่าย ก่อนอื่นต้องเข้าใจได้ก่อนว่าโค้ดนั้นทำงานอย่างไร -
ความคาดเดาได้
ความคาดเดาได้ (Predictability) หมายถึง เพื่อนร่วมทีมที่ทำงานร่วมกันสามารถคาดเดาพฤติกรรมของฟังก์ชันหรือคอมโพเนนต์ได้มากน้อยเพียงใด โค้ดที่มีความคาดเดาได้สูงจะปฏิบัติตามกฎที่สม่ำเสมอ และสามารถรู้ได้ว่าทำงานอย่างไรเพียงดูชื่อของฟังก์ชันหรือคอมโพเนนต์ พารามิเตอร์ และค่าที่ส่งกลับ -
ความสอดคล้องภายใน
ความสอดคล้องภายใน (Cohesion) หมายถึง โค้ดที่ต้องแก้ไขนั้นถูกแก้ไขไปพร้อมกันเสมอหรือไม่ โค้ดที่มีความสอดคล้องภายในสูงจะไม่ทำให้เกิดข้อผิดพลาดในส่วนอื่นโดยไม่ตั้งใจเมื่อแก้ไขโค้ดบางส่วน เพราะมีโครงสร้างที่รองรับให้ส่วนที่ต้องแก้ไขร่วมกันถูกแก้ไขไปพร้อมกันอย่างแน่นอน -
การพึ่งพากัน
การพึ่งพากัน (Coupling) หมายถึง ขอบเขตของผลกระทบเมื่อมีการแก้ไขโค้ด โค้ดที่มีผลกระทบน้อยเมื่อแก้ไข และสามารถคาดเดาขอบเขตของการเปลี่ยนแปลงได้ คือโค้ดที่แก้ไขได้ง่าย
8 ความคิดเห็น
อยากทราบว่าทำไมถึงใช้ไฟล์เป็นหน่วยการจัดการขั้นต่ำของคอมโพเนนต์และฮุก เดาว่าอาจเป็นเพราะการรองรับของ IDE หรือ tree shaking ยังไม่ดีพอ แต่ก็ไม่แน่ใจเลยอยากถามให้ชัดเจน
เวลาอ่านโค้ดแล้วเจอไฟล์ที่มีแค่ฟังก์ชันเดียว หรือไฟล์
index.tsที่มีเพียงคำสั่ง import export ก็รู้สึกว่าสิ่งที่ต้องจำเพิ่มขึ้นนะครับ/ค่ะ เมื่อเทียบกับการผสมฮุกและคอมโพเนนต์ไว้ในไฟล์เดียว ผม/ฉันคิดว่าเป็นการจัดวางที่เพิ่มภาระทางความคิดเกินความจำเป็น ถึงอย่างนั้นก็ยังมีข้อดีหรือเหตุผลอะไรที่ทำให้เลือกใช้การจัดวางแบบนั้นไหม?โดยปกติแล้ว สมมติฐานสำคัญของ "การพัฒนาที่ดี" ที่พูดกันในบริบทแบบนี้คือมีนักพัฒนาจำนวนมากกำลังทำงานอยู่ร่วมกัน
อย่างที่คุณบอกว่า สิ่งที่ต้องจำเพิ่มขึ้นเรื่อย ๆ = หมายความว่าตัวคุณเองรับผิดชอบต่อทั้งโปรเจกต์ทั้งหมด แต่
ในสภาพแวดล้อมที่มีนักพัฒนาจำนวนมาก แต่ละคนก็พัฒนาเฉพาะส่วนที่ตัวเองรับผิดชอบ
ถ้ามีปัญหาเกิดขึ้น ก็แค่ดูส่วนนั้นก็พอ ไม่จำเป็นต้องไปดูทุกส่วนที่เกี่ยวข้องทั้งหมด
จะมองว่าเป็นการเลือกผลิตภาพแทนการทำ optimization แบบสุดโต่งก็ได้
อย่างที่คุณกล่าวไว้ ในสภาพแวดล้อมที่สามารถแบ่งหน้าที่งานย่อยได้ละเอียด การเลือกตามเนื้อหาในบทความก็ถือว่าเหมาะสม ผมคิดว่าหากอธิบาย trade-off ตอนแยกโค้ดและเกณฑ์ในการตัดสินใจไว้ด้วย บทความจะสมบูรณ์ยิ่งขึ้น
สำหรับกรณีของผม เหตุผลที่ใช้ไฟล์เป็นหน่วยจัดการที่เล็กที่สุดของคอมโพเนนต์หรือฮุกเวลา做 Frontend มีดังนี้
กล่าวคือ จับคู่หนึ่งโมดูลกับหนึ่งยูนิตเทสต์ได้ง่าย
ผมคิดว่าการพัฒนา Frontend มีแนวคิดที่ยึด pure function เป็นหลัก แต่ถ้ามีหลายฟังก์ชันอยู่ในไฟล์เดียว เวลาจะเขียนยูนิตเทสต์จะจับคู่แบบ 1 ต่อ 1 ได้ยาก
ถ้าในไฟล์เดียวอย่าง
remark-plugin.jsมี utility function หลายตัวอยู่ เราควรเขียนเทสต์อย่างไรดี? การสร้างไฟล์remark-plugin.test.jsแค่ไฟล์เดียวแล้วเขียนเทสต์ของ utility function หลายตัวรวมกันทีเดียว เป็นทางเลือกที่ดีจริงหรือ?ในสถานการณ์แบบนี้ ถ้าสร้างไดเรกทอรีชื่อ
remark-pluginsแล้วแยก utility function ออกเป็นตัว ๆ ข้างในเพื่อเขียนเทสต์ ผมคิดว่าจะมีข้อดี เช่น ภายหลังทำให้บทบาทของฟังก์ชันชัดเจนขึ้น และการติดตามคอมมิตบน GitHub ก็สะอาดขึ้นมากด้วยตัว bundle โมดูลอย่าง commonjs ฝั่งเซิร์ฟเวอร์ หรือ webpack ฝั่งไคลเอนต์ มักกำหนดให้ไฟล์
index.jsเป็นไฟล์ทางเข้าของไดเรกทอรีหนึ่ง ๆ นี่ก็เป็นธรรมเนียมที่ใช้กันมานาน จึงมีส่วนหนึ่งที่แค่ยอมรับและใช้ตามกันมาแต่สำหรับผม เหตุผลที่สำคัญที่สุดคือ ในแนวคิด pure function ของการเขียนโปรแกรมเชิงฟังก์ชัน เราไม่ควรพึ่งพา state ภายนอก ดังนั้นถ้ามีหลายฟังก์ชันกองรวมอยู่ในไฟล์เดียว ผมคิดว่าความเสี่ยงที่จะเผลออ้างอิง state ภายนอกจะสูงขึ้น (ลองนึกถึงเหตุผลที่มี module scope ใน ES6 ดูก็น่าจะช่วยได้)
ส่วนตัวแล้วผมรู้สึกว่า เมื่อเทียบกับการมี utility function หลายตัวปะปนอยู่ในไฟล์เดียว ถ้าแยกฟังก์ชันออกเป็นแต่ละไฟล์ การตามดู commit history จะง่ายกว่ามาก
เมื่อมีการเพิ่มฟีเจอร์หรือแก้บั๊กในโมดูลใดโมดูลหนึ่ง ก็ไม่ต้องไปอ้างอิงโมดูลอื่น และโฟกัสที่โมดูลเดียวได้เลย
พอเขียนไปเขียนมา ข้อความก็ยาวเลยออกจะเรียบเรียงไม่ค่อยเป็นระเบียบสักหน่อยนะครับ (ตอนนี้ผมยังเข้าใจเรื่อง tree shaking ไม่มากนัก เลยขอไม่พูดเยอะดีกว่า...) แน่นอนว่าสิ่งที่ผมพูดอาจไม่ใช่คำตอบที่ถูกต้องเสมอไป ดังนั้นถ้ามองเป็นข้อมูลอ้างอิงประกอบก็น่าจะดีครับ!
อันนี้ดีนะ
เขียนได้ลื่นไหล อ่านง่ายมากครับ/ค่ะ แนะนำเลย
ขอบคุณที่แชร์ครับ/ค่ะ! ผม/ฉันเองก็ต้องอ่านอย่างละเอียดเหมือนกันครับ/ค่ะ
แม้จะเขียนโดยจำกัดอยู่ที่ FE แต่ก็รู้สึกว่าเป็นเรื่องราวที่นำไปปรับใช้ได้ดีกับซอฟต์แวร์ทั่วไป ขอบคุณที่แบ่งปันมุมมองที่ดีครับ