ทำความรู้จักกับ Micro Frontend

Putt Potsawee
LifeatRentSpree
Published in
4 min readJun 11, 2021

Microservice เป็น architecture ที่กำลังเป็นที่แพร่หลายอย่างมากสำหรับการทำ Backend ในปัจจุบันนี้ ตั้งแต่ Microservice ถูกนำมาใช้มากขึ้น เราก็เห็นเทคโนโลยี และ architecture ต่างๆ ที่มาช่วยส่งเสริมให้การพัฒนาระบบแบบ Microservice เป็นไปอย่างถูกต้องและตอบโจทย์กับประโยชน์ที่จะได้รับของ Microservice มากขึ้น ไม่ว่าจะเป็น Container Orchestration หรือ Event-driven architecture

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

บทความนี้เราจะมาเล่าคอนเซปต์นั้น สิ่งที่น่าสนใจ ประโยชน์ในการใช้มัน

และในบทความต่อไป เราจะลงลึกในส่วนที่สำคัญและควรคิดถึง และพูดคุยกันในทีม ก่อนการเอาคอนเซปต์นี้ไปพัฒนาจริงๆ

นิยามของ Micro Frontend

ในส่วนของ Microservice เราจะไม่กล่าวถึงมากในบทความนี้ แต่สรุปสั้นๆ Microservice คือ architecture ในการแบ่งระบบออกเป็นส่วนๆ ที่ทำงานแยกขาดจากกัน มีความง่ายต่อการ Deploy และ Scale ไม่พังง่าย

โดย Micro Frontend จะมีคอนเซ็ปต์ที่ลอกมาจาก Microservice อยู่ไม่น้อยเหมือนกัน นิยามของมันคือ

แนว Architect ที่ Frontend application แต่ละแอพ แยกเป็นอิสระต่อกัน สามารถนำมารวมกันเป็นหนึ่งเดียวได้

An architectural style where independently deliverable frontend applications are composed into a greater whole

ด้วยความที่คอนเซ็ปต์ของมันยังไม่ได้ถูกนำไปใช้แพร่หลายในวงกว้าง เราจะมาวิเคราะห์เทรนด์ของมันก่อน

When it becomes trend

ภาพจาก thoughtworks.com

ตาม ThoughtWork Technology Radar แล้ว คอนเซ็ปต์ Micro Frontend ถูกวางไว้ดังนี้

  • 2016 ถูกลิสไว้ใน “Assess” (ควรค่าแก่การลองศึกษา และทำความเข้าใจ)
  • 2017 ขยับมาที่ “Trial” (ควรค่าแก่การติดตาม และนำไปลองใช้)
  • 2018 ยังอยู่ที่ “Trial”
  • 2019 ขยับมาที่ “Adopt” (แนะนำให้เอามาใช้ ThoughtWork เองก็เอามาใช้แล้ว)

ซึ่งในปี 2020 ThoughtWork ก็ได้ออกข้อควรระวังขึ้นมาที่ชื่อว่า Micro Frontend Anarchy ว่าด้วยเรื่องความสับสนของ คอนเซ็ปต์ Micro Frontend

Thoughtwork พบว่ามีการนำ Micro Frontend ไปใช้เป็นข้ออ้างในการเอาหลายๆ เทคโนโลยีมาผสมปนกันใน Frontend อย่างเช่นเอา Angular มาผสมกับ React.js ซึ่งเป็นสิ่งที่ไม่แนะนำให้ทำ ถ้าในบริษัทไม่ได้กำลังปรับทิศทางไปในเชิง เปลี่ยนผ่านเทคโนโลยี (transition strategy) ยกตัวอย่างเช่น ถ้าเอา Micro Frontend ไปใช้ เมื่อต้องการเปลี่ยนจาก jQuery ไปเป็น React โดยใช้ Micro Frontend มาทำให้สามาถเอา app react ผสมเข้าไปใน jQuery application ตัวอย่างนี้สามารถทำได้ และไม่ถือเป็น Micro Frontend Arnachy แต่ถ้าเอา Micro Frontend มาใช้ เพราะทีมสองทีม ตกลงกันไม่ได้ และจะใช้เทคโนโลยีคนละตัวกันไปตลอด อันนี้ไม่แนะนำให้ใช้

Why

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

แม้จะแบ่งหลายทีมดูแล service แต่ UI ก็ยังต้องเอามารวมอยู่ที่เดียว

Benefit

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

ซึ่งประโยชน์จากการนำ Micro Frontend มาใช้จะมีด้วยกันดังนี้

  • Incremental Upgrades
    ในเชิงของการอัพเกรดหรือเปลี่ยนแปลงเทคโนโลยีของ Frontend เราไม่จำเป็นต้องรื้อหน้า หรือเปลี่ยนใหม่พร้อมกันทั้งหมด เราสามารถใช้ Micro Frontend อัพเกรดไปทีละส่วนได้
  • Simple, Decoupled codebase
    Codebase ที่ถูกแบ่งเป็นส่วนๆ ทำให้มันมี Low coupling, High Cohesion และยังทำให้เส้นแบ่งของ Bounded Context มีความชัดเจนมากขึ้น เป็นไปตาม Principle ของ Microservice เท่ากับว่าการใช้ Micro Frontend จะช่วยทำให้ประโยชน์ที่ได้รับจาก Microservice ชัดเจนขึ้นได้อีกด้วย
  • Independent Deployment
    ช่วยลดสโคปของการ deploy แต่ละครั้ง Frontend application แต่ละส่วนมี CD Pipeline ของตัวเอง
แต่ละ Micro Frontend มี pipeline ของตัวเอง (ภาพจาก martinfowler.com)
  • Autonomous Team
    ทำให้ทีมที่ดูแลพัฒนาส่วนของ Application ทำงานได้ด้วยตัวเองอย่างเป็นอิสระ มีความเป็นเจ้าของ (ownership) ในทุกๆ อย่างที่ส่งมอบให้ลูกค้า

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

Integration

ก่อนจะเล่าในส่วนของ Integration จะขอชูความสำคัญขอหัวข้อนี้ก่อน มันมีคำกล่าวของ Microservice ในหนังสือ Building Microservice (Newman, 2015) กล่าวว่า

การทำ Integration ให้ถูกต้องนั้นเป็นแง่มุมที่สำคัญที่สุด ในเทคโนโลยีที่เกี่ยวข้องกับ Microservice

Getting integration right is the single most important aspect of the technology associated with microservices

การ Integrate ส่วนต่างๆ ให้ถูกต้องนั้นเป็นเรื่องที่สำคัญ ไม่ใช่ว่าเราทำให้ service สองตัวคุยกันได้ ก็ถือว่า Integrate สำเร็จแล้ว แม้ว่า service จะคุยกันได้ แต่ถ้าแบบแผนในการ integrate ไม่ถูกต้อง มันจะต้องมีปัญหาตามมาแน่นอน

ดังนั้น เราจะมาเล่าถึงหลักการและความสำคัญของ Integration แต่ละแบบ

Integration Concept

คอนเซ็ปต์ของการ Integration นั้นโดยรวมแล้วไม่ได้ยากอะไร เราต้องการจะใส่ Micro Frontend แอพแต่ละตัวลงในแต่ละหน้า (page) ของ application โดยมี Container Application ตัวนึง ที่มีหน้าที่ นำ Micro Frontends แต่ละตัวมาประกอบกัน และทำหน้าที่ Render องค์ประกอบที่ใช้ร่วมกัน เช่น Header เป็นต้น นอกจากนี้ Container Application ตัวนี้จะต้องจัดการฟีเจอร์โดยรวม อย่างเช่น Authentication หรือ Navigation ด้วย

ภาพจาก martinfowler.com

โดยวิธีในการ Integration นั้นถูกแบ่งได้เป็นแต่ละแบบดังนี้

  • Server-side template composition
  • Build-time integration
  • Run-time Integration

โดยในบทความนี้เราจะมาเจาะลึกเกี่ยวกับ Run-time Integration แต่ก่อนหน้านั้น ต้องเล่าถึงสองอันแรกก่อน

Server-side template composition

ภาพจาก martinfowler.com

แบบนี้ยกมาเป็นกรณีศึกษาได้ วิธีการทำงานของมันคือแค่ container app ไปเรียก HTML fragment จาก Micro Frontend server อีกตัว ตรงไปตรงมา คล้ายๆ Templating engine ใน framework ต่างๆ เช่น blade, handlebar แต่ดึง HTML จาก server อื่นได้

โค้ดจาก martinfowler.com

ซึ่งในตัวอย่างนี้ อยากแสดงให้เห็นว่า แค่ Nginx โค้ดง่ายๆ เราก็สามารถ implement ตัว Micro Frontend แบบนึงได้แล้ว

โค้ดจาก martinfowler.com

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

Build-time Integration

โค้ดจาก martinfowler.com

ในแบบนี้จะเป็นการเอา application มารวมกันตอน build มองง่ายๆ ก็คือการ include module ของ Micro Frontend ใน package.json ของ Container Application

แบบนี้ทำได้ง่ายและไม่ได้ ต้องการเทคนิคอะไรมาก เรายังคงได้ codebase ที่แยกขาดจากกันในแต่ละแอพอยู่ แต่จะมีข้อเสียคือ โปรเจคจะต้อง re-compile ใหม่ทุกครั้งที่ มีการขึ้น Micro Frontend อันใดอันหนึ่ง ไม่สามารถแยก CD Pipeline ได้ ทำให้เกิด Lockstep release และถือเป็น Release Coupling กล่าวคือคือเวลาจะ release แอพนึง จะไปกระทบกับอีกแอพนึงได้

เป็นวิธีที่ทำได้ง่าย แต่ไม่แนะนำ

Run-time integration

การเอา Micro Frontend แต่ละตัวมารวมกันตอน Run time ไปเลย วิธีนี้จะทำให้ได้ CD Pipeline แยกขาดออกจากกันได้ง่าย ยังแบ่งเป็นวิธี implement ได้ สามวิธีด้วยกัน

via iframes

วิธีหนึ่งที่เอามาใช้ได้นั่นก็คือใช้ iframe โดยธรรมชาติของมันแล้ว iframe มีหน้าที่ทำสิ่งนี้เลย นั่นก็คือเอา page เล็กๆ มายัดใส่ใน page หลัก โดยตัว iframe ก็ยังสามารถทำให้เราแยกส่วนประกอบของ page เช่น Styling หรือ Global Variable ออกจากกันได้ง่าย

แต่ตัว iframe ก็ยังมีปัญหา ที่มัน integrate กับหน้าหลักยาก มันทำให้การทำ routing, history และ deep-linking ยากไปอีก ยังไม่นับว่า การจะทำให้หน้า iframe เป็น fully responsive นั้นเป็นโจทย์ที่ยากพอตัวเลย

via JavaScript

วิธีนี้น่าจะเป็นวิธีที่ยืดหยุ่นที่สุด มีคนเอาไปใช้บ่อยที่สุด วิธีของมันก็คือการเอา entry-point ของ Micro Frontend ไปไว้ใน global functionโดยที่ Container Application จะดูว่าต้องเอา Micro Frontend ตัวไหนมา Mount ลงไป

ซึ่งวิธีการข้างต้นอาจจะดูง่ายๆ ตรงไปตรงมาเพื่อสาธิต เทคนิคนี้ ในแบบ JavaScript นี้เราสามารถ deploy bundle.js ของแต่ละ Micro Frontend แยกจากกันได้อย่างชัดเจนมาก และเรายังสามารถปรับปรุงเพิ่มเติม โค้ดด้านบนได้อีกหลากหลาย ด้วยความยืดหยุ่นแบบนี้เองทำให้วิธีนี้เป็นวิธีหลักเลยที่เราจะเลือกมาใช้ทำ Micro Frontend กัน

เราจะมีอีกบทความหนึ่ง สาธิตการแปลง Boilerplate ของ React ที่เป็น production-ready อย่าง react-boilerplate ให้เป็น Micro Frontend ให้ชมกัน โปรดติดตาม

via Web Components

แบบสุดท้ายที่จะกล่าวถึง นั่นก็คือวิธีที่ให้ Micro Frontend แต่ละอัน แปลงเป็น Custom HTML (Web Component) เพื่อให้ Container เอาไปใช้

ผลลัพธ์ของวิธีนี้จะคล้ายคลึงกับวิธีก่อนหน้านี้มาก ความต่างหลักๆ เลยคือมันใช้ Web Component ในการ render ซึ่งทำให้เราต้องใช้ตาม Web Component spec ไปโดยปริยาย มันมีข้อดีคือใช้ง่าย เป็น standard และไม่ซับซ้อน แต่ข้อเสียคือ Web Component ยังเป็น feature ใหม่ของ Browser อยู่ การรองรับยังไม่แพร่หลายใน Browser เก่าๆ และเราจะต้อง integrate ตาม spec ของ Web Component เท่านั้น

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

การทำ Micro Frontend นั้นจะให้ด้านการแยก Codebase ให้มี High Cohesion, Low Coupling แบ่งระบบให้สอดคล้องกับ Microservice แยก deployment เป็นอิสระต่อกัน ทำแบบนี้ก็จะทำให้ทีมที่ดูแลแอพ Micro Frontend สามารถทำงานได้ด้วยตัวเอง เป็นอิสระไม่ต้องพึ่งทีมอื่นๆ นอกจากนี้เรายังใช้ Micro Frontend เพื่อ Incremental upgrade ใช้เปลี่ยนเทคโนโลยี Frontend ของเราได้อีกด้วย

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

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

และในบทความสุดท้าย เราจะสาธิตการเปลี่ยนโครง React ที่มีความเป็น Production-ready เป็นอย่างสูง อย่าง React-boilerplate ให้เป็น Micro Frontend (โปรดติดตามผ่าน RentSpree Medium)

--

--

Putt Potsawee
LifeatRentSpree

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