6 สิ่งที่ต้องคิด เมื่อจะเลือกใช้ Micro Frontend

Putt Potsawee
LifeatRentSpree
Published in
6 min readJun 18, 2021
Photo by Kevin Butz on Unsplash

ในบทความที่แล้ว เราได้เล่าถึงคอนเซปต์ของ Micro Frontend ประโยชน์ที่จะได้รับ ถ้าเอามาปรับใช้ ซึ่งในเชิงเทคนิคแล้ว การจะพัฒนาแอพให้มีสถาปัตยกรรมแบบ Micro Frontend นั้น เรียกว่าไม่ยากเลยก็ว่าได้

แต่สิ่งที่สำคัญมากกว่าในการนำวิธีการพัฒนาใหม่ๆมาใช้ นั่นก็คือการคิดถึงความเปลี่ยนแปลงใน process การพัฒนา และการจัดการกับปัญหาจากความเปลี่ยนแปลงที่จะตามมาเนื่องจากวิธีพัฒนาใหม่ๆ นั่นเอง ซึ่ง Micro Frontend ก็ไม่เว้นจากข้อนี้

สิ่งต่างๆ เหล่านี้เป็นสิ่งที่จะต้องวิเคราะห์ วางแผน และพูดคุยกันในทีมพัฒนา ในบทความนี้เราจะลองเอาสิ่งที่ต้องวิเคราะห์ทั้งหมดนั้นมาลองดูกันว่ามีแง่มุมอะไรบ้างที่น่าสนใจ น่าเอาไปวิเคราะห์ และพูดคุยตกลงกันในทีม ก่อนจะเอา Micro Frontend ไปปรับใช้

และในบทความถัดไป บทความสุดท้าย เราจะเอา Micro Frontend ไปปรับใช้กับ โครง React-Boilerplate เพื่อดูความเป็นไปได้ในการเอา Micro Frontend ไปใช้ใน Production (โปรดติดตามผ่าน RentSpree Medium)

สิ่งที่ต้องคิด เมื่อจะเลือกใช้ Micro Frontend มีดังต่อไปนี้

  1. Styling การทำ style ของหน้าแอพ
  2. Shared component library การทำ Library เพื่อเอามาแชร์กันระหว่า Micro Frontend แอพ
  3. Cross-application communication การสื่อสารระหว่างแอพหลายๆ แอพ
  4. Backend Communication
  5. Testing
  6. Downsides ข้อเสียต่างๆ ของการนำ Micro Frontend มาใช้ ที่ต้องเตรียมจัดการแก้ไข

Styling

Photo by Bryony Elena on Unsplash

สิ่งแรกที่แอพ Micro Frontend ต้องคิดถึงเลย ก็คือการจัดการ Styling เพราะในแอพ Frontend ส่วนใหญ่เราจะคุ้นกับ Styling แบบรวมกันที่เดียว ไม่ได้กระจายไปตามส่วนต่างๆ

ทั้งนี้ การแยกแอพให้ย่อย เป็นแอพ Micro Frontend เล็กๆ ไม่ได้ทำให้ปัญหา CSS ที่เจอกันอยู่แล้วในแอพขนาดใหญ่ลดลงไปแต่อย่างใด แต่ในทางตรงกันข้ามมันจะมีแต่ทวีความรุนแรงขึ้น ยกตัวอย่างเช่น การแยก codebase จะทำให้ Selector ของ CSS อยู่แยกโปรเจคกัน และหากมี commit โค้ดโดยทีมสองทีมที่มาในเวลาไล่เลี่ยกัน หรือพร้อมๆ กันโอกาสที่ CSS จะทับกันก็มีมากขึ้น นั่นเอง

ในปัจจุบัน แทบจะไม่มีใครขึ้นโปรเจคใหม่ๆ ด้วย Pure CSS แล้ว เราจะเห็นวิธีการจัดการ CSS ที่หลากหลาย และง่ายมากขึ้น แต่ละแบบจะมีข้อดีข้อเสียแตกต่างกันออกไป ตัวอย่างการใช้ Convention อย่าง BEM ก็จะทำให้จัดการ CSS selector ได้ชัดเจน เข้มงวด และ scale ได้ง่ายขึ้น หรือจะเป็น lib ที่ช่วย extend CSS อย่าง SASS ที่เพิ่มฟีเจอร์ให้จัดการ selector nesting และใช้ namespace ได้ ก็มีประโยชน์มากเหมือนกัน

และสุดท้ายคงหนีไม่พ้น lib ที่เป็น CSS-in-JS อย่าง styled component ที่ช่วยให้เราเขียน CSS ลงใน JavaScript ได้ง่าย และชัดเจนมากขึ้น น่าจะเป็นตัวเลือกแรกของการทำ SPA ใหม่ๆ ในปัจจุบันเลยก็ว่าได้

ไม่ว่าจะใช้วิธีไหน ก็ไม่ได้สำคัญกับ Micro Frontend มากนัก สิ่งสำคัญที่สุดที่ต้องคำนึงถึงคือ ควรทำให้ Developer สามารถเขียน style ได้อย่างเป็นอิสระ และมีความมั่นใจว่า style ที่เขียนไปจะใช้งานได้ไม่มีปัญหาใน production ดังนั้น วิธีการจัดการแบบใหม่ๆ ที่เน้นเรื่องนี้ อาจจะเหมาะกับการทำ Micro Frontend มากกว่า ในขณะที่วิธีแบบอื่น อาจจะต้องมีการ config อะไรเพิ่มเติม เพื่อให้การเขียน style เป็นไปได้อย่างอิสระ ไม่มีปัญหานั่นเอง

Shared Component Library

Photo by Paul Melki on Unsplash

เมื่อมีการแยกทีมทำโปรเจค ก็ต้องมีปัญหาในการเอา Component ที่ใช้ร่วมกันมาแชร์กัน เพื่อให้โค้ดนั้น DRY และ maintain ง่าย อีกทั้งยังสามารถคุม Style ให้เหมือนกันได้ง่าย

การทำ UI Component Library จึงเป็นสิ่งที่จะสร้างประโยชน์ให้กับทีมได้อย่างมาก แต่จะทำได้อย่างไร มันก็มีอยู่สองวิธีหลักๆ ด้วยกัน

แบบแรกก็คือสร้าง Foundation Framework ขึ้นมาเลย ประกาศ Component ที่จะใช้ไว้ก่อนล่วงหน้าทั้งหมด ข้อดีคือ component ก็จะ consistent กันตั้งแต่เริ่มต้น แต่จะมีปัญหาก็คือมันเป็นไปได้ยากที่จะคาดการณ์ component ที่จะใช้ล่วงหน้า และต่อให้ใช้ไปแล้ว สุดท้ายก็จะมี component บางอันที่ไม่ค่อยได้ใช้ ถูกทิ้งไว้เปล่าๆ

อีกแบบนึงจะเป็นเทคนิคที่ตรงกันข้าม เรียกว่า Harvested Framework จะใช้วิธีว่า ในช่วงแรกๆ ให้แต่ละทีมทำ component ของตัวเองขึ้นมาก่อนเลย ยอมให้มันมีของซ้ำได้ ซึ่งตัวของซ้ำนี่เองที่จะทำให้เราเห็น patttern ว่า อะไรใช้บ่อย อะไรควรเอามาแชร์ แล้วสุดท้ายก็ทำการเก็บเกี่ยว (harvest) ส่วนที่ซ้ำกันมาเป็น Library ที่แชร์กันในทีม

ไม่ว่าจะใช้วิธีไหน สิ่งที่สำคัญมากๆ คือ component พวกนี้ต้องเป็น “dumb” component ที่แสดงผลเท่านั้น ต้องดูให้ดีว่ามันมีแค่ UI Logic และไม่ได้มี business หรือ domain logic ใน component เหล่านั้น

และอีกส่วนนึงที่ต้องทำความเข้าใจให้ตรงกันในทีม ก็คือการควบคุมดูแล และสร้างความเป็นเจ้าของ component เหล่านั้น (Ownership & Governance) แต่การที่จะบอกว่า ทุกคนในทีม มีหน้าที่ดูแล และเป็นเจ้าของ component นั้น แทบจะไม่ต่างอะไรกับการบอกว่า ไม่มีใครมีหน้าที่ดูแล และเป็นเจ้าของพวกมันเลย สิ่งที่ควรจะทำก็คือแต่งตั้งกลุ่มคนในทีม (custodian) ที่มีหน้าที่ควบคุมดูแล component พวกนั้นในเชิง คุณภาพ ความสอดคล้อง และความถูกต้อง

Cross-application Communication

Photo by Debby Hudson on Unsplash

ประเด็นที่สำคัญที่สุด ที่สืบเนื่องมาจากการ Integration ก็คือการติดต่อ ส่งข้อมูลระหว่าง Micro Frontend

แค่ทำให้สองโปรแกรมคุยกันได้ จริงๆ ไม่ใช่โจทย์ที่ยากอะไรเลย แต่มันมีประเด็นสำคัญให้วิเคราะห์ และออกแบบให้ดีก่อนที่จะตัดสินใจทำในส่วนนี้

อย่างแรกและสำคัญที่สุด การที่เราเอา Micro Frontend มาใช้ตั้งแต่ต้น เพราะเราอยากให้ Codebase เราแบ่งเป็นสัดส่วน ทำงานแยกต่างหากกันได้ ทำให้ทีมแต่ละทีมดูแล Codebase ของตัวเอง สามารถทำงานได้อย่างอิสระ เมื่อคิดถึง communication ระหว่าง Micro Frontend แล้ว เราจึงควรที่จะทำให้มี communication ระหว่างกันให้น้อยที่สุดเท่าที่เป็นไปได้ เพื่อทำให้มี Coupling ระหว่างทีมให้น้อยที่สุด

ข้อนี้ รวมไปถึงการพยายามหลีกเลี่ยงไม่ให้ Micro Frontend แต่ละอันมี state ที่ใช้ร่วมกัน (Shared State) ให้มากที่สุดด้วย

อย่างที่สอง เมื่อจำเป็นต้องมี communication เราจำเป็นต้องมีแบบแผนในการสื่อสารที่ตกลงกันระหว่างแต่ละทีม เป็นการสื่อสารระหว่าง Micro Frontend แต่ละอันไปด้วย สิ่งนี้เป็นสิ่งที่สำคัญมาก เราเรียกมันว่า Contract (สัญญา) ซึ่งมันเป็นสิ่งที่แต่ละทีมต้องตกลงกันตั้งแต่ต้น และเป็นหัวใจของการสื่อสารทั้งหมด เป็นสิ่งที่เปลี่ยนทีหลังได้ยาก และต้องเข้าใจตรงกันในแต่ละทีมที่พัฒนา Micro Frontend ด้วย

ซึ่งเราจะเห็นว่า การส่งค่าระหว่าง Micro Frontend นี้เราก็เลือกวิธีง่ายๆ อย่าง Custom Events มาใช้ก็ได้ ถ้าใช้วิธีนี้ ด้วยความที่มันเป็น Event มันช่วยลด coupling ระหว่างผู้รับกับผู้ส่งได้ดีเลย แต่ถ้าลองพิจารณา Event ที่จะส่งออกไป เราจะเห็นว่า ผู้ส่งสามารถเลือกส่ง event อะไรก็ได้ (ส่ง JavaScript Object หน้าตาแบบไหนก็ได้) ซึ่งทางผู้รับก็ต้องรับให้ตรงกัน ถึงจะสื่อสารกันได้ จะเห็นว่า รูปแบบการส่ง จำเป็นต้องมีการตกลงกันให้ชัดเจนในแต่ละ event เลย เพื่อลดความผิดพลาดที่จะเกิดขึ้นจากการสื่อสาร ทำให้ต้องมีความจำเป็นที่จะเอา pattern อย่าง Customer-driven contracts มาใช้เพื่อควบคุม ทดสอบในส่วนนี้ และกลายมาเป็น effort ในการพัฒนาที่เพิ่มขึ้นในที่สุด

Cross-application communication via Routing

วิธีหนึ่งที่ง่ายและมีประโยชน์มาก คือการกำหนดให้การสื่อสารระหว่างแต่ละ Micro Frontend ทำได้ผ่าน Routing เท่านั้น

ภาพจาก martinfowler.com

โดยวิธีนี้ก็คือแค่ทำให้ Page URL เป็นวิธีการส่งข้อมูลระหว่าง Micro Frontend วิธีเดียวเท่านั้น แต่ละแอพสื่อสารผ่าน Page URL ดังตัวอย่างในรูป เมื่อแอพ Browse ต้องการปรับหน้าจากการคลิก และส่ง idของร้านอาหารที่ผู้ใช้งานคลิก ก็แค่ปรับ page URL ให้เป็นไปตามที่ต้องการ แล้วแอพ Order ก็ดึงการเปลี่ยนแปลงมาจาก page URL แล้วจัดการไปตามนั้น

ตัว URL เมื่อใช้ร่วมกัน มันมีข้อดีคือ

  • มันมีโครงสร้างที่ถูกกำหนดไว้ชัดเจน เป็นมาตรฐาน (rfc3986: URL ประกอบด้วย domain, path, query เป็นต้น)
  • โค้ดทุกส่วนที่รันใน Browser สามารถเข้าถึง URL ได้ เป็นแบบ Global อยู่แล้ว
  • User-facing คือผู้ใช้งานก็เห็น URL ที่ขึ้นบน Browser ตลอด
  • Declarative กล่าวคือ มันจะบอกว่า “เราอยู่ที่ไหน” ไม่ใช่ “ให้ทำอะไร”

ด้วยข้อดีดังนี้เอง Route ที่ใช้ ก็จะเป็น Contract ในรูปแบบหนึ่งนั่นเอง และเป็น contract ที่ค่อนข้างสะดวก กล่าวคือ แต่ละแอพตกลงที่จะสื่อสารกันผ่าน Routing ทำให้ไม่ต้องมากำหนด contract ส่วนที่เป็น format เพราะ URL มีโครงสร้างชัดเจน ทุกคนรู้จัก URL อยู่แล้ว นอกจากนี้ contract ที่ได้ยัง develop ง่ายเพราะมันเป็น user-facing และ declarative เป็นต้น

มันจึงเป็นวิธีที่ถูกแนะนำเป็นอันดับแรก เพราะได้ข้อดีครบ และไม่ต้องพัฒนาอะไรเพิ่มเติม

อย่างไรก็ดี การใช้ Routing ไม่ใช่วิธีเดียว ในส่วนของ Communication นี้ขึ้นอยู่กับผู้ออกแบบระบบ ทีมแต่ละทีมที่พัฒนาจะตกลงร่วมกัน ไม่ว่าจะใช้วิธีไหน ก็ยังคงต้องคำนึงถึงหัวข้อต่างๆ ที่กล่าวไว้ด้านบนทั้งหมด

ในบทความที่สาธิตการแปลง React-boilerplate ให้เป็น Micro-frontend เราก็จะนำวิธีการ communicate แบบ routing นี้มาใช้ให้ดูกัน (โปรดติดตามผ่าน RentSpree Medium)

Backend Communication

ในการติดต่อกับ Backend ของ Micro Frontend นั้นไม่ได้มีข้อบังคับอะไรเป็นพิเศษ เราสามารถออกแบบระบบให้ติดต่อกับ Backend แบบไหนก็ได้ที่เหมาะสมกับรูปแบบองค์กรและ Business ที่ซอฟต์แวร์ของเรานั้นรันอยู่

อย่างไรก็ตาม จะมี pattern การออกแบบ Backend แบบหนึ่งที่น่าสนใจ สำหรับ Full Stack Team กล่าวคือทีมสามารถดูแลซอฟต์แวร์ทั้งหมดได้ตั้งแต่ Backend ไปจนถึง Frontend ในลักษณะนี้ pattern การออกแบบที่ชื่อว่า Backend-for-Frontend (BFF)

ภาพจาก martinfowler.com

การออกแบบใน pattern นี้ จุดเด่นก็คือการกำหนดไว้เลยว่า Frontend แอพนึงจะมี Backend เพียงแค่อันเดียวมารองรับ แล้วถ้ามี service หรือ backend อื่นๆ ตัว BFF จะไปเรียกในระบบหลังบ้านเอาเอง หรือ BFF จะมี database ของตัวเองเลยก็ได้

Pattern แบบนี้จะช่วยลด Coupling ระหว่างทีมได้เป็นอย่างดี นั่นคือถ้ามีการเปลี่ยน backend ที่เป็น BFF เช่นเปลี่ยน Endpoint บางตัว ก็จะการันตีได้ว่าจะไม่ไปกระทบ Frontend แอพอื่น (จากในรูปจะมีแค่การเปลี่ยน Downstream service เท่านั้นที่จะกระทบ BFF ที่มาเรียก)

อย่างไรก็ดี การทำ BFF แบบนี้ก็จะต้องแก้ปัญหาที่ตามมาจากการแยกส่วน Backend (ปัญหาส่วนใหญ่ที่มักจะเจอใน Microservice) เช่นการทำ Authentication ที่จะต้องทำให้ BFF ทำงานได้ภายใต้ Authentication เดียวกัน ซึ่งวิธีแก้นึงก็คือการส่ง Token ผ่านไปยัง Micro Frontend แต่ละตัว ให้เรียก Backend ด้วย token จาก source เดียวกัน

Testing

Photo by National Cancer Institute on Unsplash

ในส่วนของการทดสอบระบบนั้น เป็นส่วนหนึ่งที่จะไม่ค่อยแตกต่างกันกับระบบแบบ Monolith นั่นก็คือเราสามารถใช้ Test Strategy แบบเดียวกับ Monolith app ได้เลย การแบ่งเป็น Micro Frontend นั้นไม่ทำให้รูปแบบการทดสอบเปลี่ยนแปลง

ที่เห็นได้ชัดคงจะเป็นการทำ Functional Testing หรือ End-to-end testing ในส่วนนี้ไม่ควรจะแตกต่างกับการทำแอพทั่วๆ ไป ยกตัวอย่างเช่นการใช้ Cypress หรือ Selenium เพื่อ automate การทดสอบฟังก์ชั่น ปุ่มต่างๆ ซึ่งตัวทดสอบก็จะมองภาพ Frontend ของเรา เหมือนที่ user มองเห็น นั่นก็คือไม่มีความแตกต่าง ในส่วนของการเขียนเทส เราก็สามารถเขียนได้ปกติตามแบบของ Cypress หรือ Selenium ได้เลย

และในส่วนของ unit-testing ถึงจะแบ่งเป็น Micro Frontend เราก็ยังต้องทำ unit-testing สำหรับ low-level business logic และทดสอบการ render component ต่างๆ ไม่ต่างอะไรกับแอพทั่วไปเลย (ขอย้ำ เขียน Unit-Test กันด้วยแม้จะเป็น Frontend มันมีประโยชน์มากๆ และไม่ได้ทำให้การพัฒนาช้าลงเลย)

Downsides

ไม่มี architecture แบบไหนที่ไม่มีข้อเสีย หัวใจสำคัญของการเลือก architecture คือการดูข้อดี และพยายามจัดการกับข้อเสียของ architecture แบบนั้นๆ Micro Frontend ก็เช่นกัน ในส่วนนี้นี้เราพูดถึงข้อดีส่วนมากของ Micro Frontend กันแล้ว ตอนนี้เราจะมาดูข้อเสียของมันกันบ้าง

Payload Size

Photo by freestocks on Unsplash

แน่นอน เมื่อแยกส่วนแอพออกมาเป็น Micro Frontend แยกต่างหากกัน แต่ละแอพจำเป็นต้องแยก Javascript bundle ออกมาเป็นของตัวเอง นั่นทำให้เกิด Dependency ที่ซ้ำ กันในแต่ละ bundle ซึ่งก็จะเพิ่มจำนวนของ bytes ที่ต้องส่งผ่านใน network ไปถึง บราวเซอร์ของผู้ใช้งาน ยกตัวอย่างเช่นถ้า Micro Frontend แต่ละแอพ รวม React ของใน bundle ไปด้วย เท่ากับว่า เราบังคับให้ผู้ใช้งานของเราต้องโหลด lib React เป็นจำนวนเท่ากับแอพ Micro Frontend ที่มีในระบบของเรา มีรายงานว่าประสิทธิภาพในการโหลดหน้าเว็บส่งผลกับ Engagement และ Conversion ของผู้ใช้งาน โดยตรง เพราะฉะนั้นเราจึงจำเป็นต้องให้ความสำคัญกับ size ของ bundle ที่ผู้ใช้งานต้องดาวน์โหลดเป็นอย่างมาก

ซึ่งปัญหานี้เป็นปัญหาที่ไม่ง่ายเลย มันมีข้อขัดแย้งของความต้องการให้ทีมแต่ละทีมสามารถ compile แอพของตัวเองได้อย่างอิสระ เพื่อให้ทีมสามารถทำงานได้ด้วยตนเอง แต่ในเชิง payload size เราก็ต้องการจะสร้างแอพให้สามารถแชร์ dependency ให้ได้มากที่สุด วิธีแก้หนึ่งของปัญหานี้ก็คืออาจจะใช้การแยก dependency ที่แต่ละ Micro Frontend ใช้ออกมา built รวมกันต่างหาก เช่นกำหนดให้มี dependency lib เป็น CDN กลางอยู่ตัวนึง แล้วทุกทีมตกลงกันว่าจะใช้ dependency version นี้เท่านั้น วิธีนี้ดูจะแก้ปัญหาได้ง่ายๆ ไม่มีอะไร แต่จริงๆ มันเป็นการเพิ่ม build-time coupling เช่นถ้าต้องมีการแก้ไขอะไรที่เป็น Breaking Change ใน dependency เราจำเป็นต้องประสานงานกับทุกทีม ทำให้มันการเปลี่ยน lock step release ซึ่งเราพยายามหลีกเลี่ยงมาตั้งแต่ต้นด้วยการเลือกใช้ Micro Frontend

ถึงข้อขัดแย้งข้างต้นจะเป็นปัญหาที่ยาก แต่ก็ไม่ใช่ทุกอย่างจะแย่ไปซะหมด หากเราเลือกที่จะไม่ทำอะไรกับ duplicate dependency ที่เกิดขึ้น มันก็มีความเป็นไปได้ที่ page ของแอพแบบ Micro Frontend จะโหลดเร็วกว่าแอพ Monolith ทั่วๆ ไป เหตุผลก็คือการแบ่งส่วนของแอพให้เป็น Micro Frontend อาจจะทำให้เราได้ Code Splitting แบบนึง ซึ่งก็อาจจะส่งผลให้แอพโหลดเร็วขึ้นในหน้าแรก แต่อาจจะต้องมีการโหลดเพิ่มเติมบ้างในหน้าอื่นๆ

อย่างไรก็ดี จะเห็นว่ามันยังมีความไม่แน่นอนอยู่ในปัญหานี้ค่อนข้างเยอะ ทำให้ถ้าหากเราจะเลือกใช้ Micro Frontend เราต้องเตรียมที่จะจัดการตรงนี้ เพราะแอพพลิเคชั่นต่างๆ จะมีคุณสมบัติในเรื่อง performance แตกต่างกันออกไป ข้อสำคัญในการจัดการ performance คือเราต้องจัดการคอขวด (Bottle Neck) ในเรื่อง performance ให้ดี เพราะถึงแม้เราจะลด Payload size ให้เล็กลงไปเหลือไม่กี่ KB แล้ว แต่ถ้าเว็บยังมีส่วนอื่นที่โหลดช้า มีคอขวดที่การ query databse แอพของเราก็ยังถือว่า performance ไม่ดี เพราะฉะนั้น การจะทำแอพให้มี performance ที่ดีคงต้องดูให้ครบ และจัดการให้ภาพรวมดีที่สุด จึงจะได้ผลลัพธ์ที่เป็นประโยชน์นั่นเอง

Environment Differences

Photo by NOAA on Unsplash

ประโยชน์ของ Micro Frontend นั้นคือเราต้องพัฒนาแอพ Micro Frontend เดี่ยวๆ ได้โดยที่ไม่ต้องคำนึงถึงแอพ Micro Frontend ที่ถูกพัฒนาโดยทีมอื่นๆ เราต้องสามารถรัน Micro Frontend ของเราได้ในแบบ Standalone mode บน local ของเราด้วยซ้ำ การรันแบบ Standalone นี้จะช่วยให้เราพัฒนาแอพได้รวดเร็วมากยิ่งขึ้นอย่างแน่นอน แต่การทำแบบนั้นก็จะนำมาซึ่งความเสี่ยง เมื่อเราพัฒนาแอพใน environment ที่ไม่เหมือนกับใน production เช่นถ้ามีอะไรบางอย่างใน container ที่ทำให้ production environment แตกต่างจาก local ก็อาจจะนำไปสู่การเกิดบัคได้

วิธีแก้ปัญหาในส่วนนี้คือ เราต้องทำให้แน่ใจว่าแอพ Micro Frontend ของเรานั้นได้ถูก integrate และ deploy เข้าไปใน environment ที่เหมือนกับ production อย่างสม่ำเสมอ เช่นอาจจะเซ็ต CI/CD ให้เมื่อ push code ใน staging แล้ว Micro Frontend ถูกนำไป integrate กับแอพอื่นๆ ใน dev environment แล้วมี process ให้ทีมเข้าไปเทสในนั้นก่อน release ขึ้น production จริง ก็จะช่วยลดความเสี่ยงตรงนี้ได้

Operational and Governance Complexity

Photo by Christina @ wocintechchat.com on Unsplash

แน่นอน ปัญหานี้ก็จะเป็นปัญหาที่มาพร้อมกับ distributed architecture แบบที่ Microservice ต้องพบเจอเลย นั่นก็คือการกระจายระบบออกเป็นส่วนย่อยๆ แบ่งๆ กันทำ มันหมายถึงว่า เราต้องจัดการส่วนที่กระจายออกไปมากขึ้น มี Repository มากขึ้น ต้องใช้ Tool ที่หลากหลายมากขึ้น Build/Deploy Pipeline ที่มีจำนวนมากขึ้น ใช้ทรัพยากรพวก server และ domain มากขึ้น สิ่งเหล่านี้จะเพิ่มความซับซ้อนให้การทำงานของทีมเราอย่างแน่นอน

เพราะฉะนั้น ก่อนที่จะเอา Micro Frontend ไปใช้ เราอาจจะต้องถามตัวเองหลายๆ คำถามก่อน เรามี automation pipeline เพียงพอต่อการที่จะจัดการ infrastructure ที่ซับซ้อนขึ้นเหล่านี้ หรือไม่? Process การพัฒนา Frontend ทดสอบและ release สามารถ scale ไปหลายแอพได้หรือไม่? ทีมเราโอเคหรือไม่ที่จะให้การตัดสินใจเกี่ยวกับเครื่องมือที่ใช้ และ development practice กระจายไปตามทีมต่างๆ และควบคุมได้ยากขึ้น? และเราจะสามารถทำให้แน่ใจได้อย่างไรว่า Frontend codebase ที่แยกกันจะมีคุณภาพ มี consistency เป็นไปในทางเดียวกัน?

ข้อสำคัญที่อยากให้นำไปใช้ก็คือ ถ้าเลือก Micro Frontend แล้ว ทิศทางของการพัฒนามันจะไปในทาง การสร้างสิ่งเล็กๆ หลายๆ สิ่ง มากกว่าสร้างสิ่งใหญ่ๆ สิ่งเดียว เราต้องประเมินว่าในองค์กรมีความรู้ความสามารถ มีความพร้อมที่จะนำ Micro Frontend นี้ไปใช้แบบไม่เกิดปัญหาได้ และที่สำคัญกว่านั้น มันคุ้มหรือไม่ ที่เราจะนำ Micro Frontend มาใช้?

ไม่มี Architecture แบบใดแบบหนึ่งที่จะดีที่สุด และเป็นคำตอบของทุกๆ ปัญหา ในทางกลับกัน การเลือก Architecture นั้นต้องพิจารณาข้อดีข้อเสีย ของ Architecture แบบต่างๆ ก่อนนำไปปรับใช้จริง ซึ่งในการเลือกใช้ Micro Frontend ที่เน้นการกระจาย codebase และแอพ Frontend ออกเป็นส่วนย่อยๆ นั้น เราต้องคิดถึงการจัดการที่มากขึ้น Communication ระหว่างแอพที่ต้องมีการตกลงกันให้เป็น pattern ที่จะไม่ก่อให้เกิดปัญหาในอนาคต การใช้ซ้ำ การจัดการ duplicate dependency ซึ่งจะส่งผลกระทบต่อ process การพัฒนาและอาจจะเป็นปัญหาเรื่อง Payload Size ได้

นอกจากนี้เรื่อง Styling และ Testing ยังเป็นอีกสองเรื่องที่สำคัญไม่แพ้กัน ซึ่งหากทีมต้องการจะเลือกนำ Micro Frontend ไปใช้แล้ว ในการจัดการกับปัญหาเหล่านี้ ก็ยังต้องคำนึงถึงข้อดีและสาเหตุที่เราเลือก Micro Frontend มาใช้ด้วย เพราะถ้าจัดการปัญหาเหล่านั้นได้ แต่ต้องเสียข้อดีของการนำ Micro Frontend มาใช้แล้ว มันอาจจะไม่คุ้มที่จะนำมาใช้เลย การบริหาร Trade off จึงเป็นสิ่งที่สำคัญที่สุดในขั้นตอนการเลือก Architecture นั่นเอง

ในบทความสุดท้าย เราจะสาธิตการเอา React-Boilerplate มาปรับให้เป็น Micro Frontend และลงลึกเกี่ยวกับวิธีการพัฒนาจริงๆ จะเป็นอย่างไร โปรดติดตามผ่าน RentSpree Medium

Reference

บทความนี้ได้รับอิทธิพลและเนื้อหาส่วนใหญ่จาก Blog ใน martinfowler.com บวกกับความเห็นและข้อคิดจากการพูดคุยกันในทีม RentSpree

--

--

Putt Potsawee
LifeatRentSpree

Lead Developer at RentSpree. Passionate programmer who specialized in Backend and Infrastructure.