จุดแข็งและประโยชน์ของไมโครฟรอนท์เอนด์

เผยแพร่แล้ว: 2022-03-11

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

ประโยชน์ของรูปแบบไมโครฟรอนท์เอนด์ ได้แก่:

  1. สถาปัตยกรรมไมโครฟรอนท์เอนด์อาจง่ายกว่า และทำให้ให้เหตุผลและจัดการได้ง่ายขึ้น
  2. ทีมพัฒนาอิสระสามารถทำงานร่วมกันบนแอปส่วนหน้าได้ง่ายขึ้น
  3. พวกเขาสามารถจัดเตรียมวิธีการโยกย้ายจากแอป "เก่า" โดยให้แอป "ใหม่" ทำงานเคียงข้างกัน

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

ในบทความนี้ เราจะข้ามไปเกี่ยวกับทฤษฎีส่วนหน้าของไมโคร นี่คือสิ่งที่เรา จะไม่กล่าว ถึง:

  • “สไลซ์” แอพให้เป็นไมโครแอพ
  • ปัญหาการปรับใช้ รวมถึงวิธีที่ไมโครฟรอนต์เอนด์พอดีกับโมเดล CI/CD
  • การทดสอบ
  • ไมโครแอพควรอยู่ในแนวเดียวกับไมโครเซอร์วิสบนแบ็กเอนด์หรือไม่
  • คำติชมของแนวคิดไมโครฟรอนท์เอนด์
  • ความแตกต่างระหว่างไมโครฟรอนต์เอนด์และสถาปัตยกรรมคอมโพเนนต์แบบเก่าทั่วไป

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

การดำเนินการของเราเรียกว่า Yumcha ความหมายตามตัวอักษรของ “ยำชะ” ในภาษากวางตุ้งคือ “ดื่มชา” แต่ความหมายในชีวิตประจำวันคือ “ออกไปกินติ่มซำ” แนวคิดในที่นี้คือไมโครแอปแต่ละตัวภายใน มาโครแอป (ดังที่เราเรียกว่าแอประดับบนสุดที่เรียบเรียง) มีความคล้ายคลึงกับตะกร้าขนาดพอดีคำหลายๆ ตะกร้าที่นำออกมารับประทานในมื้อเที่ยงของติ่มซำ

ภาพประกอบภาพรวมของแอพตัวอย่างไมโครฟรอนท์เอนด์ตามที่อธิบายไว้ข้างต้น

บางครั้งเราจะเรียก Yumcha ว่าเป็น "กรอบงานไมโครฟรอนท์เอนด์" ในโลกปัจจุบัน คำว่า "เฟรมเวิร์ก" มักใช้เพื่ออ้างถึง Angular, React, Vue.js หรือโครงสร้างเสริมอื่นๆ ที่คล้ายกันสำหรับเว็บแอป เราไม่ได้พูดถึงกรอบการทำงานในแง่นั้นเลย เราเรียก Yumcha ว่าเป็นกรอบงานเพียงเพื่อความสะดวก: แท้จริงแล้วมันเป็นชุดเครื่องมือมากกว่าและมีเลเยอร์บางๆ สองสามชั้นสำหรับการสร้างแอปแบบไมโครฟรอนท์เอนด์

บทแนะนำไมโครฟรอนต์เอนด์ ขั้นตอนแรก: มาร์กอัปสำหรับแอปที่เรียบเรียง

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

 <html> <head> <script src="/yumcha.js"></script> </head> <body> <h1>Hello, micro-frontend app.</h1> <!-- HERE ARE THE MICROAPPS! --> <yumcha-portal name="microapp1" src="https://microapp1.example.com"></yumcha-portal> <yumcha-portal name="microapp2" src="https://microapp2.example.com"></yumcha-portal> </body> </html>

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

เราได้ตั้งชื่อองค์ประกอบแบบกำหนดเองที่ใช้สำหรับ microapps <yumcha-portal> เนื่องจาก "พอร์ทัล" เป็นคำศัพท์ที่น่าสนใจสำหรับ microapps ที่ใช้ในข้อเสนอพอร์ทัล ซึ่งเป็นความพยายามในการกำหนดองค์ประกอบ HTML มาตรฐานสำหรับใช้ในไมโครฟรอนท์เอนด์

การใช้ <yumcha-portal> Custom Element

เราควรใช้ <yumcha-portal> อย่างไร? เนื่องจากเป็นองค์ประกอบที่กำหนดเอง เป็นส่วนประกอบเว็บ แน่นอน! เราสามารถเลือกจากคู่แข่งที่แข็งแกร่งจำนวนหนึ่งสำหรับการเขียนและรวบรวมส่วนประกอบเว็บไมโครฟรอนท์เอนด์ ที่นี่เราจะใช้ LitElement ซึ่งเป็นการทำซ้ำล่าสุดของโครงการโพลีเมอร์ LitElement รองรับน้ำตาลซินแทคติกบน TypeScript ซึ่งจัดการส่วนประกอบที่กำหนดเองส่วนใหญ่สำหรับเรา เพื่อให้ <yumcha-portal> พร้อมใช้งานบนหน้าเว็บของเรา เราต้องรวมโค้ดที่เกี่ยวข้องเป็น <script> ตามที่เราได้ทำไว้ข้างต้น

แต่ <yumcha-portal> ทำอะไรได้บ้าง? การประมาณค่าแรกคือการสร้าง iframe ด้วยแหล่งที่มาที่ระบุ:

 render() { return html`<iframe src=${this.src}></iframe>`; }

…โดยที่การ render นเดอร์คือเบ็ดการเรนเดอร์ LitElement มาตรฐาน โดยใช้เทมเพลตที่ติดแท็ก html ฟังก์ชันขั้นต่ำนี้อาจเพียงพอสำหรับกรณีการใช้งานเล็กน้อย

การฝัง Microapps ใน iframe s

iframe เป็นองค์ประกอบ HTML ที่ทุกคนชอบที่จะเกลียด แต่จริงๆ แล้ว พวกมันมีพฤติกรรมการทำแซนด์บ็อกซ์ที่มีประโยชน์อย่างมากและแข็งแกร่ง อย่างไรก็ตาม ยังมีรายการปัญหาอีกมากที่ควรทราบเมื่อใช้ iframe ซึ่งมีผลกระทบต่อการทำงานและการทำงานของแอปของเรา:

  • ประการแรก iframe มีนิสัยใจคอที่รู้จักกันดีในแง่ของขนาดและการจัดวาง
  • แน่นอนว่า CSS จะถูก แยกออก จาก iframe โดยสิ้นเชิง ไม่ว่าจะดีขึ้นหรือแย่ลง
  • ปุ่ม "ย้อนกลับ" ของเบราว์เซอร์จะทำงานได้ดีพอสมควร แม้ว่า สถานะการนำทางปัจจุบันของ iframe จะไม่ปรากฏใน URL ของหน้า เราจึงไม่สามารถตัดและวาง URL เพื่อไปยังสถานะเดียวกันของแอปที่แต่ง หรือลิงก์ในรายละเอียด ถึงพวกเขา.
  • การสื่อสารกับ iframe จากภายนอก ขึ้นอยู่กับการตั้งค่า CORS ของเรา อาจต้องผ่านโปรโตคอล postMessage
  • ต้องมีการเตรียมการสำหรับการ ตรวจสอบสิทธิ์ข้ามขอบเขตของ iframe
  • โปรแกรมอ่านหน้าจอบางตัวอาจสะดุด ที่ขอบของ iframe หรือต้องการให้ iframe มีชื่อที่สามารถประกาศให้ผู้ใช้ทราบได้

ปัญหาเหล่านี้บางอย่างสามารถหลีกเลี่ยงหรือบรรเทาได้โดยไม่ใช้ iframe ซึ่งเป็นทางเลือกที่เราจะพูดถึงในบทความต่อไป

ในด้านบวก iframe จะมี Content-Security-Policy (CSP) อิสระเป็นของตัวเอง นอกจากนี้ หากไมโครแอพที่ iframe ชี้ให้ใช้พนักงานบริการหรือใช้การเรนเดอร์ฝั่งเซิร์ฟเวอร์ ทุกอย่างจะทำงานตามที่คาดไว้ เรายังระบุตัวเลือกแซนด์บ็อกซ์ต่างๆ ให้กับ iframe เพื่อจำกัดความสามารถของ iframe ได้ เช่น ความสามารถในการนำทางไปยังเฟรมบนสุด

เบราว์เซอร์บางตัวได้จัดส่งไปแล้วหรือกำลังวางแผนที่จะจัดส่งแอตทริบิวต์ loading=lazy สำหรับ iframe s ซึ่งเลื่อนการโหลด iframe ครึ่งหน้าล่างออกไป จนกว่าผู้ใช้จะเลื่อนเข้าไปใกล้ๆ แต่ไม่ได้ให้การควบคุมที่ละเอียดของการโหลดแบบ Lazy Loading พวกเราต้องการ.

ปัญหาที่แท้จริงของ iframe คือเนื้อหาของ iframe จะใช้คำขอเครือข่ายหลายรายการเพื่อดึงข้อมูล ได้รับ index.html ระดับบนสุด โหลดสคริปต์ และแยกวิเคราะห์ HTML แล้ว—แต่จากนั้นเบราว์เซอร์ต้องเริ่มต้นคำขออื่นสำหรับ HTML ของ iframe รอรับ แยกวิเคราะห์และโหลดสคริปต์ และแสดงผล เนื้อหาของ iframe ในหลายกรณี JavaScript ของ iframe จะยังคงต้องหมุน ทำการเรียก API ของตัวเอง และแสดงข้อมูลที่มีความหมายหลังจากการเรียก API เหล่านั้นกลับมาเท่านั้น และข้อมูลจะได้รับการประมวลผลสำหรับการดู

ซึ่งอาจส่งผลให้เกิดความล่าช้าที่ไม่พึงประสงค์และการเรนเดอร์อาร์ติแฟกต์ โดยเฉพาะอย่างยิ่งเมื่อมีไมโครแอพหลายตัวเข้ามาเกี่ยวข้อง หากแอปของ iframe ใช้ SSR จะช่วยได้ แต่ก็ยังไม่หลีกเลี่ยงความจำเป็นสำหรับการเดินทางไปกลับเพิ่มเติม

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

เซิร์ฟเวอร์ Yumcha

องค์ประกอบหลักของโซลูชันไมโครฟรอนท์เอนด์ที่นำเสนอในที่นี้คือการตั้งค่าเซิร์ฟเวอร์เฉพาะเพื่อจัดการองค์ประกอบของไมโครแอพ พร็อกซีเซิร์ฟเวอร์นี้ร้องขอไปยังเซิร์ฟเวอร์ที่โฮสต์ไมโครแอพแต่ละตัว จริงอยู่ที่ต้องใช้ความพยายามในการตั้งค่าและจัดการเซิร์ฟเวอร์นี้ วิธีการไมโครฟรอนท์เอนด์บางอย่าง (เช่น single-spa) พยายามที่จะแจกจ่ายโดยไม่จำเป็นต้องตั้งค่าเซิร์ฟเวอร์พิเศษดังกล่าว ในนามของความง่ายในการปรับใช้และการกำหนดค่า

อย่างไรก็ตาม ค่าใช้จ่ายในการตั้งค่าพร็อกซีย้อนกลับนี้มากกว่าการชดเชยด้วยผลประโยชน์ที่เราได้รับ อันที่จริง มีพฤติกรรมที่สำคัญของแอปบนไมโครฟรอนท์เอนด์ที่เราทำไม่ได้หากไม่มีแอปดังกล่าว มีทางเลือกเชิงพาณิชย์และฟรีมากมายในการตั้งค่า reverse proxy

พร็อกซีย้อนกลับ นอกเหนือจากการกำหนดเส้นทางคำขอ microapp ไปยังเซิร์ฟเวอร์ที่เหมาะสม ยังกำหนดเส้นทางคำขอของ macroapp ไปยังเซิร์ฟเวอร์ macroapp เซิร์ฟเวอร์นั้นจัดเตรียม HTML สำหรับแอปที่แต่งขึ้นด้วยวิธีพิเศษ เมื่อได้รับคำขอสำหรับ index.html จากเบราว์เซอร์โดยใช้พร็อกซีเซิร์ฟเวอร์ที่ URL เช่น http://macroapp.example.com จะดึงข้อมูล index.html จากนั้นจึงเปลี่ยนรูปแบบที่เรียบง่ายแต่มีความสำคัญก่อนส่งคืน มัน.

โดยเฉพาะอย่างยิ่ง HTML ถูกแยกวิเคราะห์สำหรับแท็ก <yumcha-portal> ซึ่งสามารถทำได้ง่ายด้วยหนึ่งในตัวแยกวิเคราะห์ HTML ที่มีความสามารถที่มีอยู่ในระบบนิเวศ Node.js การใช้แอตทริบิวต์ src กับ <yumcha-portal> เซิร์ฟเวอร์ที่เรียกใช้ microapp จะได้รับการติดต่อและดึงข้อมูล index.html ของเซิร์ฟเวอร์ รวมถึงเนื้อหาที่แสดงฝั่งเซิร์ฟเวอร์ หากมี ผลลัพธ์จะถูกแทรกลงในการตอบสนอง HTML เป็นแท็ก <script> หรือ <template> เพื่อไม่ให้เบราว์เซอร์ดำเนินการ

ภาพประกอบสถาปัตยกรรมเซิร์ฟเวอร์ของ Yumcha เบราว์เซอร์สื่อสารกับ reverse proxy ซึ่งจะสื่อสารกับ macroapp และ microapp แต่ละตัว ขั้นตอนของ macroapp จะแปลงและเติมไฟล์ index.html หลักของแอปไว้ล่วงหน้า

ข้อดีของการตั้งค่านี้ ได้แก่ ประการแรกและสำคัญที่สุด ในคำขอแรกสุดสำหรับ index.html สำหรับหน้าที่เรียบเรียง เซิร์ฟเวอร์สามารถดึงหน้าแต่ละหน้าจากเซิร์ฟเวอร์ microapp แต่ละรายการอย่างครบถ้วน ซึ่งรวมถึงเนื้อหาที่แสดงผลด้วย SSR ถ้า ใดๆ—และส่งหน้าเพจที่สมบูรณ์เพียงหน้าเดียวไปยังเบราว์เซอร์ ซึ่งรวมถึงเนื้อหาที่สามารถใช้เพื่อเติม iframe โดยไม่ต้องเดินทางไปกลับของเซิร์ฟเวอร์เพิ่มเติม (โดยใช้แอตทริบิวต์ srcdoc ที่ไม่ได้ใช้) พร็อกซีเซิร์ฟเวอร์ยังช่วยให้แน่ใจว่ารายละเอียดใด ๆ ของที่ที่ไมโครแอพถูกเสิร์ฟนั้นถูกปิดบังจากการสอดรู้สอดเห็น ในที่สุด มันช่วยลดความซับซ้อนของปัญหา CORS เนื่องจากคำขอแอปพลิเคชันทั้งหมดถูกสร้างขึ้นจากแหล่งกำเนิดเดียวกัน

กลับมาที่ไคลเอ็นต์ แท็ก <yumcha-portal> จะได้รับการสร้างอินสแตนซ์และค้นหาเนื้อหาที่อยู่ในเอกสารการตอบกลับโดยเซิร์ฟเวอร์ และในเวลาที่เหมาะสมจะแสดงผล iframe และกำหนดเนื้อหาให้กับแอตทริบิวต์ srcdoc หากเราไม่ได้ใช้ iframe s (ดูด้านล่าง) เนื้อหาที่สอดคล้องกับแท็ก <yumcha-portal> นั้นจะถูกแทรกลงใน shadow DOM ขององค์ประกอบที่กำหนดเอง หากเราใช้สิ่งนั้น หรืออินไลน์ในเอกสารโดยตรง

ณ จุดนี้ เรามีแอปที่ทำงานบนไมโครฟรอนท์เอนด์บางส่วนแล้ว

นี่เป็นเพียงส่วนเล็กของภูเขาน้ำแข็งในแง่ของฟังก์ชันการทำงานที่น่าสนใจสำหรับเซิร์ฟเวอร์ Yumcha ตัวอย่างเช่น เราต้องการเพิ่มคุณสมบัติเพื่อควบคุมวิธีจัดการกับการตอบสนองข้อผิดพลาด HTTP จากเซิร์ฟเวอร์ microapp หรือวิธีจัดการกับ microapps ที่ตอบสนองช้ามาก เราไม่ต้องการรอตลอดไปเพื่อให้บริการหน้าถ้า microapp หนึ่งไม่ได้ ตอบสนอง! หัวข้อเหล่านี้และหัวข้ออื่น ๆ ที่เราจะฝากไว้สำหรับโพสต์อื่น

ลอจิกการแปลง Yumcha macroapp index.html สามารถใช้งานได้ง่ายในรูปแบบฟังก์ชันแลมบ์ดาไร้เซิร์ฟเวอร์ หรือเป็นมิดเดิลแวร์สำหรับเฟรมเวิร์กเซิร์ฟเวอร์ เช่น Express หรือ Koa

การควบคุม Microapp แบบอิงสตับ

เมื่อย้อนกลับไปที่ฝั่งไคลเอ็นต์ มีอีกแง่มุมหนึ่งที่เราปรับใช้ไมโครแอปซึ่งมีความสำคัญต่อประสิทธิภาพ การโหลดแบบ Lazy Loading และการแสดงผลที่ปราศจากปัญหา เรา สามารถ สร้างแท็ก iframe สำหรับแต่ละไมโครแอปได้ ไม่ว่าจะด้วยแอตทริบิวต์ srcdoc src กรอกด้วยเนื้อหาที่เซิร์ฟเวอร์เติมให้เรา แต่ในทั้งสองกรณีนี้ โค้ดใน iframe นั้นจะเริ่มต้นทันที รวมถึงการโหลดสคริปต์และแท็กลิงก์ทั้งหมด การบูตสแตรป และการเรียก API เริ่มต้นและการประมวลผลข้อมูลที่เกี่ยวข้อง แม้ว่าผู้ใช้จะไม่เคยเข้าถึงไมโครแอปที่เป็นปัญหาก็ตาม

วิธีแก้ไขปัญหานี้คือในขั้นต้นแสดงไมโครแอปบนหน้าเป็นต้นขั้วที่ปิดใช้งานขนาดเล็ก ซึ่งสามารถเปิดใช้งานได้ การเปิดใช้งานสามารถถูกขับเคลื่อนโดยภูมิภาคของ microapp ที่เข้ามาดู โดยใช้ IntersectionObserver API ที่ไม่ได้ใช้ หรือโดยทั่วไปมากกว่าปกติโดยการแจ้งเตือนล่วงหน้าที่ส่งจากภายนอก แน่นอน เรายังสามารถระบุให้เปิดใช้งาน microapp ได้ทันที

ไม่ว่าในกรณีใด เมื่อใดและเฉพาะเมื่อเปิดใช้งานไมโครแอพ iframe จะถูกแสดงผลจริงและมีการโหลดและดำเนินการโค้ด ในแง่ของการใช้งานของเราโดยใช้ LitElement และสมมติว่าสถานะการเปิดใช้งานแสดงโดยตัวแปรอินสแตนซ์ที่ activated เราจะมีลักษณะดังนี้:

 render() { if (!this.activated) return html`{this.placeholder}`; else return html` <iframe srcdoc="${this.content}" @load="${this.markLoaded}"></iframe>`; }

การสื่อสารระหว่างไมโครแอพ

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

เพื่อให้สอดคล้องกับกรอบความคิดแบบมินิมัล เราต้องการหลีกเลี่ยงการแนะนำกลไกการส่งข้อความจำนวนมาก แต่ด้วยจิตวิญญาณขององค์ประกอบของเว็บ เราจะใช้เหตุการณ์ DOM แทน เราจัดเตรียม API การแพร่ภาพแบบไม่สำคัญที่แจ้งเตือนล่วงหน้าสำหรับต้นขั้วทั้งหมดของเหตุการณ์ที่กำลังจะเกิดขึ้น รอจนกว่าจะมีการร้องขอให้เปิดใช้งานสำหรับประเภทเหตุการณ์นั้นที่จะเปิดใช้งาน จากนั้นจึงส่งเหตุการณ์ไปยังเอกสาร ซึ่ง microapp ใด ๆ ก็สามารถรับฟังได้ มัน. เนื่องจาก iframe ทั้งหมดของเรามีต้นทางเดียวกัน เราจึงสามารถเข้าถึงจาก iframe ไปที่หน้าและในทางกลับกันเพื่อค้นหาองค์ประกอบที่จะเริ่มต้นเหตุการณ์

การกำหนดเส้นทาง

ในยุคนี้ เราทุกคนต่างคาดหวังให้แถบ URL ใน SPA แสดงถึงสถานะการดูของแอปพลิเคชัน ดังนั้นเราจึงสามารถตัด วาง ส่งอีเมล ข้อความ และลิงก์ไปยังหน้าดังกล่าวเพื่อข้ามไปยังหน้าภายในแอปได้โดยตรง อย่างไรก็ตาม ในแอปไมโครฟรอนท์เอนด์ แท้จริงแล้วสถานะของแอปพลิเคชันเป็นการรวมสถานะ หนึ่งสถานะสำหรับแต่ละไมโครแอป เราจะเป็นตัวแทนและควบคุมสิ่งนี้อย่างไร?

วิธีแก้ปัญหาคือเข้ารหัสสถานะของ microapp แต่ละอันให้เป็น URL คอมโพสิตเดียว และใช้เราเตอร์ macroapp ขนาดเล็กที่รู้วิธีรวม URL คอมโพสิตนั้นเข้าด้วยกันและแยกส่วนออกจากกัน น่าเสียดายที่สิ่งนี้ต้องใช้ตรรกะเฉพาะของ Yumcha ในแต่ละไมโครแอพ: เพื่อรับข้อความจากเราเตอร์ macroapp และอัปเดตสถานะของ microapp และในทางกลับกันเพื่อแนะนำเราเตอร์ macroapp เกี่ยวกับการเปลี่ยนแปลงในสถานะนั้นเพื่อให้สามารถอัปเดตคอมโพสิต URL ตัวอย่างเช่น เราสามารถจินตนาการถึง YumchaLocationStrategy สำหรับ Angular หรือองค์ประกอบ <YumchaRouter> สำหรับ React

URL แบบผสมที่แสดงถึงสถานะ macroapp สตริงการสืบค้นจะถอดรหัสเป็นสตริงการสืบค้นที่แยกจากกัน (เข้ารหัสแบบทวีคูณ) สองชุด จากนั้นจึงส่งผ่านไปยังไมโครแอปที่มีการระบุรหัสเป็นคีย์

กรณีที่ไม่ใช่ iframe

ดังที่ได้กล่าวไว้ข้างต้น การโฮสต์ไมโครแอพใน iframe มีข้อเสียบางประการ มีสองทางเลือก: รวมไว้ใน HTML ของหน้าโดยตรง หรือวางไว้ใน Shadow DOM ทางเลือกทั้งสองสะท้อนข้อดีและข้อเสียของ iframe บ้าง แต่บางครั้งก็แตกต่างกัน

ตัวอย่างเช่น นโยบาย CSP ของ microapp แต่ละรายการจะต้องถูกรวมเข้าด้วยกัน เทคโนโลยีอำนวยความสะดวก เช่น โปรแกรมอ่านหน้าจอควรทำงานได้ดีกว่า iframe s โดยถือว่ารองรับ Shadow DOM (ซึ่งยังไม่ทั้งหมด) ควรจัดการลงทะเบียนพนักงานบริการของ microapp โดยใช้แนวคิด "ขอบเขต" ของพนักงานบริการอย่างตรงไปตรงมา แม้ว่าแอปจะต้องตรวจสอบให้แน่ใจว่าพนักงานบริการของตนลงทะเบียนภายใต้ชื่อแอป ไม่ใช่ "/" ปัญหาเลย์เอาต์ที่เกี่ยวข้องกับ iframe จะไม่มีผลกับเมธอด Inline หรือ Shadow DOM

อย่างไรก็ตาม แอปพลิเคชันที่สร้างขึ้นโดยใช้เฟรมเวิร์ก เช่น Angular และ React มักจะไม่มีความสุขในการใช้ชีวิตแบบอินไลน์หรืออยู่ใน Shadow DOM สำหรับสิ่งเหล่านั้น เราน่าจะต้องการใช้ iframe s

วิธีการ DOM แบบอินไลน์และเงาแตกต่างกันเมื่อพูดถึง CSS CSS จะถูกห่อหุ้มอย่างหมดจดใน Shadow DOM หากเราไม่ต้องการแชร์ CSS ภายนอกกับ Shadow DOM ด้วยเหตุผลบางอย่าง เราจะต้องใช้สไตล์ชีตที่สร้างได้หรือสิ่งที่คล้ายกัน ด้วยไมโครแอปแบบอินไลน์ CSS ทั้งหมดจะถูกแชร์ทั่วทั้งเพจ


ในท้ายที่สุด การใช้ตรรกะสำหรับไมโครแอพแบบอินไลน์และแชโดว์ DOM ใน <yumcha-portal> นั้นตรงไปตรงมา เราดึงเนื้อหาสำหรับ microapp ที่กำหนดจากตำแหน่งที่มันถูกแทรกลงในเพจโดยตรรกะของเซิร์ฟเวอร์เป็นองค์ประกอบ HTML <template> โคลน จากนั้นผนวกเข้ากับสิ่งที่ LitElement เรียก renderRoot ซึ่งปกติแล้วจะเป็น Shadow DOM ขององค์ประกอบ แต่สามารถทำได้ นอกจากนี้ยังตั้งค่าเป็นองค์ประกอบเอง ( this ) สำหรับกรณีอินไลน์ (ไม่ใช่เงา DOM)

แต่เดี๋ยวก่อน! เนื้อหาที่แสดงโดยเซิร์ฟเวอร์ microapp เป็นหน้า HTML ทั้งหมด เราไม่สามารถแทรกหน้า HTML สำหรับ microapp ที่มีแท็ก html , head และ body ไว้ตรงกลางหน้าสำหรับ macroapp ได้หรือไม่

เราแก้ปัญหานี้โดยใช้ประโยชน์จากส่วนโค้งของแท็ก template ที่มีการห่อเนื้อหา microapp ที่ดึงมาจากเซิร์ฟเวอร์ microapp ปรากฎว่าเมื่อเบราว์เซอร์สมัยใหม่พบแท็ก template แม้ว่าจะไม่ได้ "ดำเนินการ" แต่ก็ แยกวิเคราะห์ และในการทำเช่นนั้นพวกเขาจะลบเนื้อหาที่ไม่ถูกต้องเช่นแท็ก <html> , <head> และ <body> โดยคงไว้ซึ่งเนื้อหาภายใน ดังนั้นแท็ก <script> และ <link> ใน <head> เช่นเดียวกับเนื้อหาของ <body> จะถูกสงวนไว้ นี่คือสิ่งที่เราต้องการอย่างแม่นยำเพื่อวัตถุประสงค์ในการแทรกเนื้อหา microapp ลงในหน้าของเรา

สถาปัตยกรรมไมโครฟรอนท์เอนด์: ปีศาจอยู่ในรายละเอียด

ไมโครฟรอนท์เอนด์จะหยั่งรากในระบบนิเวศของเว็บแอพหาก (ก) กลายเป็นแนวทางสถาปัตยกรรมที่ดีกว่า และ (ข) เราสามารถหาวิธีนำไปใช้ในลักษณะที่ตอบสนองความต้องการในทางปฏิบัติมากมายของเว็บในปัจจุบัน

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

ในแง่ของการใช้งานและความเป็นไปได้ เราพบว่ามีรายละเอียดมากมายที่ต้องกังวล รวมถึงรายละเอียดที่ไม่ได้กล่าวถึงในบทความนี้ โดยเฉพาะอย่างยิ่งการรับรองความถูกต้องและความปลอดภัย การทำสำเนาโค้ด และ SEO อย่างไรก็ตาม ฉันหวังว่าบทความนี้จะนำเสนอแนวทางการนำไปใช้ขั้นพื้นฐานสำหรับไมโครฟรอนท์เอนด์ ซึ่งด้วยการปรับแต่งเพิ่มเติม สามารถตอบสนองความต้องการในโลกแห่งความเป็นจริงได้

บรรณานุกรม

  • Micro Front Ends — ทำแบบเชิงมุม — ตอนที่ 1
  • Micro Front Ends — ทำแบบเชิงมุม — ตอนที่ 2
  • การพัฒนาแอปพลิเคชัน AngularJS โดยใช้ microfrontends
  • ไมโครฟรอนต์เอนด์
  • ไมโครเซอร์วิส UI — ย้อนกลับรูปแบบการต่อต้าน (ไมโครฟรอนต์เอนด์)
  • ไมโครเซอร์วิส UI — ต่อต้านรูปแบบ?
  • การสร้างเพจโดยใช้ Micro-Frontends ใช้แนวทาง reverse proxy และ SSI ที่คล้ายกับ Yumcha ซึ่งฉันขอแนะนำเป็นอย่างยิ่ง
  • ทรัพยากรไมโครฟรอนท์เอนด์
  • แท่น
  • ฉันไม่เข้าใจไมโครฟรอนท์เอนด์ นี่เป็นภาพรวมที่ดีทีเดียวของประเภทของสถาปัตยกรรมไมโครฟรอนท์เอนด์และกรณีการใช้งาน
  • Micro-frontends แบบไร้เซิร์ฟเวอร์โดยใช้ Vue.js, AWS Lambda และ Hypernova
  • Micro Frontends: ภาพรวมที่ยอดเยี่ยมและครอบคลุม