คุณนิยมรวมหลายโปรเจ็กต์ที่เกี่ยวข้องกันแต่มีลักษณะต่างกันอย่างไร (หรือไม่รวมเลย)?
ตัวอย่างเช่น ถ้าสำหรับบริการเดียวกันมี front-end, back-end(api), serverless, batch, pipeline, ... เป็นต้น
-
Mono-repo
ถ้าเป็นบริการเดียวกัน ก็ใช้ repository เดียวไปเลย! แต่ละโปรเจ็กต์จัดเป็นโครงสร้างแพ็กเกจ/โฟลเดอร์
-> แล้วจะจัดการคอมมิตยังไง..? พวก CI/CD หรือ hook อย่าง pre-commit ก็น่าจะซับซ้อนขึ้น.. -
Git Submodules
ถ้าลักษณะงานต่างกัน อย่างน้อยก็ควรแยกจัดการ git history กันสิ! แต่ก็ยังพยายามรวมไว้ให้มากที่สุด..
-> มี learning curve เรื่อง sub module sync ฯลฯ.. การ merge ก็ซับซ้อนขึ้นด้วย.. นักพัฒนาคนอื่นจะตามทันไหม? -
repo แยกกันไป
เรียบง่าย! ถ้าเป็นคนละโปรเจ็กต์ก็แยก repository กันไปเลย!
-> ถ้าจะดูบริการ A ต้องดู repo ไหนบ้างครับ? อ้อ อันนี้ กับอันนั้น,.. แล้วมีอะไรอีกนะ...
ดูเหมือนจะไม่มีคำตอบที่ตายตัว แต่อยากรู้ว่าทุกท่านชอบแบบไหน/เพราะอะไร!
16 ความคิดเห็น
ผมชอบ repo แบบต่างคนต่างอยู่มากกว่า...
ถ้ามีคำถามขึ้นมาว่า ถ้าผมอยากดูประวัติของ API ที่เกี่ยวข้องกับฟีเจอร์นี้ ควรต้องไปดูอะไร? การจับคู่ repo หนึ่งอันกับฟีเจอร์หนึ่งอย่างชัดเจนสำหรับผมมันสะดวกกว่าครับ
โดยทั่วไปแล้วผมจะใช้ monorepo ในแทบทุกสถานการณ์ แต่มีอยู่ 2 กรณีที่ใช้ submodule ครับ
ตอนจ้างผู้รับทำ publishing ภายนอก
ถ้าไม่อยากเปิดเผยสิ่งอื่นนอกเหนือจากข้อมูลที่จำเป็นต่อการทำ publishing ให้กับผู้รับภายนอก ก็จะใช้ submodule ครับ
ตอนต้องคัสตอมไมซ์โซลูชันภายนอก
โดยเฉพาะเมื่อเป็นโซลูชันที่มีความสามารถแบบ plugin ก็จะใช้ submodule ครับ
จะลงทะเบียนโซลูชันภายนอกนั้นเป็น submodule ไว้ แล้วทำงานโดยเอา plugin ของตัวเองใส่เข้าไปใน path ของ plugin ด้วย symlink เป็นต้น plugin ของผมก็จัดการเวอร์ชันแยกกันไปตามแบบของผมได้ ขณะที่โซลูชันภายนอกก็ยังคงระบบ version control ของเขาไว้ได้เหมือนเดิม ซึ่งเป็นข้อดีครับ
ดูเหมือนว่าทุกคนจะมีประสบการณ์ที่ไม่ค่อยดีกับการใช้ submodule กันนะครับ.. ถ้ามีเครื่องมือที่ช่วยปรับปรุงเรื่องนี้ได้ก็คงดี
ถ้ามั่นใจว่าจะทำแค่ merge commit ก็ใช้ monorepo,
ถ้าจะ rebase บ่อย ๆ ก็ใช้ multi-repo,
ส่วน submodule? ใช้ directory link ที่ OS มีให้ไปเลยดีกว่า…
เมื่อก่อนผมใช้ repo แยกอิสระของใครของมันมาตลอด แต่ช่วงหลังเปลี่ยนแนวมาใช้ submodule แบบเต็มตัวแล้ว
เมื่อก่อนผมยังเข้าใจ git ไม่มากพอ เลยใช้ submodule ได้ไม่เต็มประสิทธิภาพ แต่ตอนนี้คิดว่าการใช้ submodule น่าจะดีกว่า
อย่างไรก็ตาม พอใช้ submodule ก็ต้อง commit ใน submodule นั้น แล้วกลับมา commit ที่ parent repo อีกรอบ ทำให้ช่วงเวลาของทั้งสองฝั่งเหลื่อมกัน และดูเหมือนว่าจะตามมาด้วยปัญหาที่ความสม่ำเสมอของ repo ลดลง
https://monorepo.tools/
ถ้ายังไม่เคยดูเว็บไซต์นี้ ลองเข้าไปดูสักครั้งก็น่าจะดีครับ
จากประสบการณ์ส่วนตัว ผมไม่ค่อยแนะนำ submodule ครับ
ถ้าอยากแชร์โค้ดของ repository อื่นด้วย submodule ผมว่าปล่อยเป็นแพ็กเกจน่าจะดีกว่าครับ
ในบริษัทของเรา แต่ละโปรเจ็กต์มีจำนวนสมาชิกทีมน้อย และภาษา/tech stack ของ frontend กับ backend ก็แยกจากกัน ทำให้แทบไม่มีการช่วยกันข้ามสายงาน สุดท้ายแล้วก็เหมือนระบบ IT ทั้งหลายที่มักลงเอยด้วยการสะท้อนโครงสร้างองค์กรครับ
อ้อ.. เป็นแนวทางในการปรับระดับการมองเห็นโค้ดฝั่งตรงข้ามตามว่ามนุษย์เป็นคนปรับอินเทอร์เฟซเองหรือให้เครื่องมือช่วยทำนี่เอง
ผมยังไม่มีประสบการณ์กับ Mono-repo เลย เลยมีเรื่องหนึ่งที่สงสัยครับ เวลาใช้ Mono Repo โมดูลที่ใช้ร่วมกันในหลายโปรเจกต์หรือหลายบริการ (เช่น design system) จะถูกรวมเข้าไปอยู่ใน Mono Repo แต่ละอันแบบนั้นเลยไหมครับ? หรือว่าสุดท้ายก็เลี่ยงไม่ได้ที่จะต้องแยกออกไปเป็น repo ต่างหากแล้วอ้างอิงมาใช้?
สำหรับการเข้าถึงโมดูลส่วนกลาง ดูเหมือนว่าจะใช้ตัวช่วยอย่าง yarn workspace เพื่อเข้าถึงในรูปแบบ symlink นะครับ!
ผมทั้งในที่ทำงานและโปรเจกต์ส่วนตัวจัดการทุกอย่างด้วย git เดียว โดยไม่แยก frontend, backend, batch ฯลฯ
บางครั้งการแก้ทั้งสองฝั่งไปพร้อมกันก็สะดวกกว่าการพยายามรักษา backward compatibility และทั้งสองฝั่งก็เป็นทีมขนาดเล็ก เลยรู้สึกว่าแยกออกไปก็ไม่ได้มีข้อดีอะไรเป็นพิเศษ... ส่วน GitHub Actions ก็ยอมลงทุนตั้งค่าให้รันเฉพาะส่วนที่มีการเปลี่ยนแปลงได้อยู่แล้ว ที่สำคัญกว่าการแบ่งว่าเป็น backend หรือ frontend คือแต่ละฝ่ายสามารถช่วยกันทำงานข้ามฝั่งได้ ซึ่งผมว่าดีมากกว่า (เช่น ตอนทำงานฝั่ง frontend แล้วถ้าต้องการอะไรจาก backend ก็เพิ่มเองได้เลย หรือเจอ error ก็แก้เองได้ เป็นต้น...)
อืม ดูเหมือนว่าถ้าขนาดไม่ใหญ่หรือบทบาทหน้าที่ไม่ได้แบ่งกันเข้มงวดมาก หลายคนน่าจะชอบ monorepo นะครับ! เรื่องที่ git history มันปะปนกัน? ก็ไม่ได้กังวลกันมากใช่ไหมครับ? (ยังไงก็เป็นโค้ดที่ทุกคนดูกันอยู่แล้ว?)
สิ่งที่น่าสนใจก็คือ ในโปรเจกต์ส่วนตัวของผมก็เป็นแบบนี้เหมือนกันนะครับ ตอนนี้ทำงานร่วมกับคนประมาณ 12 คน และแต่ละคนก็ทำงานตั้งแต่ฝั่งฟรอนต์เอนด์ไปจนถึงแบ็กเอนด์แบบต่อเนื่องในจังหวะเดียวกันด้วย ดูคล้ายกับ vertical slice เหมือนกันนะครับ
ผมไม่ค่อยมองว่านั่นคือการปะปนกันนะครับ เพราะบ่อยครั้งก็มีกรณีที่แก้ทั้งฝั่งฟรอนต์และแบ็กเอนด์ใน PR เดียวกัน สำหรับทีมเรา เรายึดแนวทางที่ว่าทุกคนเป็นฟูลสแตกกันทั้งหมด 4 คน ดังนั้นไม่ว่าจะเป็นแบ็กเอนด์หรือฟรอนต์เอนด์ก็ต้องรีวิวให้กันและกัน และต้องรู้ความเปลี่ยนแปลงด้วย
ถ้าโมดูลไม่ได้ใหญ่เท่าไรนัก ก็ใช้ monorepo
ถ้าโมดูลใหญ่ ก็ใช้ submodule
หรือถ้าต้องการให้ตอนปล่อยเป็นโอเพนซอร์ส เปิดให้มีส่วนร่วมเฉพาะ submodule แล้วให้ main repo จัดการกันเองภายใน
ก็ดูเหมือนว่าจะแยกเป็น submodule ครับ
แต่พอมี submodule เวลาทำเป็นโอเพนซอร์ส สำหรับผู้ใช้อื่นที่จะเข้ามามีส่วนร่วม มันก็ดูจะซับซ้อนขึ้นนิดหน่อยในเรื่องการเขียนเอกสารเกี่ยวกับการทดสอบหรือการบิลด์
ดังนั้นส่วนตัวแล้ว ถ้าไม่ใช่กรณีที่รูปแบบการมีส่วนร่วมของทั้งสองฝั่งต่างกัน
ก็มักจะใช้ monorepo หรือไม่ก็แยกไปคนละ GitHub แล้วจัดการโดยแจกจ่ายแต่ละส่วนเป็นแพ็กเกจหรือเป็น Docker image
ผมยังไม่ได้คิดในมุมของโอเพนซอร์สมาก่อนเลย ขอบคุณสำหรับความเห็นครับ!