הטמעת Single-SPA עבור Microfrontends
דמיינו שאתם עובדים על אתר מסחר אלקטרוני. הקטלוג בנוי על Next.js, חשבון המשתמש על Vue, פאנל הניהול על Angular, וכולם חייבים להופיע כ-SPA אחד. ללא Single-SPA הייתם צריכים לשכתב הכל על פריימוורק אחד – חודשים של עבודה. Single-SPA מאפשר לכם לשלב קוד קיים ללא שכתוב, תוך חיסכון של עד 40% בעלויות בהשוואה לשכתוב מלא.
נתקלנו בפרויקטים שבהם חלקים שונים של האפליקציה בנויים על פריימוורקים שונים: React לקטלוג, Vue לחשבון המשתמש, Angular למודולים legacy. שילובם ללא טעינת עמוד מלאה היא משימה לא טריוויאלית. Single-SPA פותר זאת על ידי פעולה כ-orchestrator: הוא מנהל את מחזור החיים של כל microfrontend (ויקיפדיה), מרכיב ומפרק אותם לפי URL מבלי להפריע זה לזה. בניגוד ל-Module Federation, Single-SPA הוא נייטרלי לפריימוורק – microfrontend אחד יכול להיות על React, אחר על Vue, ושלישי על Angular.
למה Single-SPA במקום Module Federation?
במבט ראשון, Module Federation (Webpack 5) נראה נוח יותר – הוא לא דורש orchestrator נפרד ועובד ברמת ה-bundler. עם זאת, יש ניואנסים:
- Module Federation קשור ל-Webpack; אם אתם משתמשים ב-Vite או בכלי build אחר, תצטרכו לשנות את שרשרת הכלים שלכם.
- הוא תומך רק בסיפורים מבודדים לכל פריימוורק אך אינו מספק ניתוב מובנה ביניהם.
- ל-Single-SPA יש מערכת אקולוגית עשירה: מתאמים מוכנים ל-React, Vue, Angular, Svelte, רכיבי parcel, ואינטגרציה עם SystemJS לניהול גרסאות.
השוואה בין Single-SPA ו-Module Federation
| מאפיין | Single-SPA | Module Federation |
|---|---|---|
| תמיכה בפריימוורקים שונים | כן | מוגבל |
| אי-תלות ב-bundler | כן | לא (Webpack 5+) |
| ניהול מחזור חיים | מובנה | דורש הגדרה ידנית |
| פיתוח מקבילי | כן | חלקי |
השוואת ביצועים: צוותים המשתמשים ב-Single-SPA מדווחים על הכשרה מהירה פי 2 למפתחים חדשים והפחתה של 30% בזמן היציאה לשוק עבור תכונות חדשות בהשוואה להגדרות Module Federation עם מספר פריימוורקים.
בעיות שאנחנו פותרים
1. התנגשויות סגנון ומצב גלובלי ללא בידוד, microfrontends דורסים CSS ומשתני window. Single-SPA ממליץ על Shadow DOM או CSS מודולרי (למשל, CSS Modules). בפרויקטים שלנו אנו משתמשים ב-postcss-prefix-selector – כל אפליקציה מקבלת קידומת מחלקה משלה.
2. ניתוב בין פריימוורקים שונים React Router, Vue Router, Angular Router – כל אחד חי בהקשר שלו. Single-SPA מיירט את כל שינויי ה-URL ומפנה אותם לאפליקציה הנכונה. אנו מגדירים את activeWhen עם ביטויים רגולריים, כך שהאפליקציה נטענת רק כאשר ה-URL תואם.
3. תקשורת בין שירותים Microfrontends צריכים להחליף נתונים: עגלת קניות, אימות, התראות. Single-SPA אינו כופה שיטה ספציפית אך ממליץ על שתי גישות:
- ייבוא בין-microfrontend דרך import map – חילוץ קוד משותף (טיפוסים, event bus) לחבילת npm נפרדת.
- CustomEvent על window – פשוט וללא תלות. דוגמה:
window.dispatchEvent(new CustomEvent('@cart/item-added', { detail: { id: '123' } })).
איך אנחנו עושים את זה: 5 צעדים לאינטגרציית Microfrontend
שלב 1: הגדרת root-config
Root-config הוא הליבה של המערכת. אנו יוצרים אותו דרך create-single-spa או ידנית:
npx create-single-spa --moduleType root-config רישום אפליקציות באמצעות npx create-single-spa --moduleType root-config :
import { registerApplication, start } from 'single-spa'
registerApplication({
name: '@company/navbar',
app: () => System.import('@company/navbar'),
activeWhen: () => true, // всегда активна
})
registerApplication({
name: '@company/catalog',
app: () => System.import('@company/catalog'),
activeWhen: (loc) => loc.pathname.startsWith('/products'),
})
start({ urlRerouteOnly: true })Index.html מכיל את ה-import map המציין גרסאות של כל microfrontend. זה מאפשר שינויי גרסאות ללא בנייה מחדש של ה-orchestrator.
שלב 2: הגדרת import map
ה-import map מצביע על כל microfrontend ל-bundle המאוחסן שלו. לדוגמה:
<script type="systemjs-importmap">
{
"imports": {
"single-spa": "https://cdn.jsdelivr.net/npm/single-spa@6/lib/es2015/esm/single-spa.min.js",
"@company/navbar": "https://cdn.example.com/navbar/latest/navbar.js"
}
}
</script>החליפו את ה-URLs בנקודות הקצה האמיתיות שלכם ב-CDN.
שלב 3: עטיפת microfrontends עם מתאמים
עבור React אנו משתמשים ב-registerApplication:
import singleSpaReact from 'single-spa-react'
import App from './App'
const lifecycles = singleSpaReact({
React,
ReactDOM,
rootComponent: App,
errorBoundary(err, info) {
return <div>Ошибка приложения: {err.message}</div>
},
})
export const { bootstrap, mount, unmount } = lifecycles
עבור Vue – import { registerApplication, start } from 'single-spa' registerApplication({ name: '@company/navbar', app: () => System.import('@company/navbar'), activeWhen: () => true, // всегда активна }) registerApplication({ name: '@company/catalog', app: () => System.import('@company/catalog'), activeWhen: (loc) => loc.pathname.startsWith('/products'), }) start({ urlRerouteOnly: true }) :
import singleSpaVue from 'single-spa-vue'
import { createApp, h } from 'vue'
import App from './App.vue'
import router from './router'
const vueLifecycles = singleSpaVue({
createApp,
appOptions: {
render() {
return h(App, this.$props)
},
},
handleInstance(appInstance) {
appInstance.use(router)
},
})
export const { bootstrap, mount, unmount } = vueLifecycles שלב 4: טיפול בתקשורת בין-פריימוורק
אנו משתמשים בשילוב של גישות:
- מודולים משותפים – חילוץ ישויות נפוצות (משתמש, עגלה) לחבילה נפרדת המיובאת מה-import map.
- CustomEvent – לאירועים נדירים (שינוי משתמש, הוספה לעגלה). זה פשוט ואמין ללא תלות נוספת.
- EventBus – ללוגיקה מורכבת אנו משתמשים במחלקת EventEmitter קטנה המועברת דרך customProps.
שלב 5: בדיקות ופריסה
- כתיבת בדיקות יחידה לכל מחזור חיים של microfrontend ובדיקות end-to-end להרכבה.
- שימוש ב-import map overrides במהלך הפיתוח.
- צינור CI/CD פורס כל microfrontend באופן עצמאי.
איך לארגן תקשורת בין Microfrontends?
אנו משתמשים בשילוב של גישות:
- מודולים משותפים – חילוץ ישויות נפוצות (משתמש, עגלה) לחבילה נפרדת המיובאת מה-import map.
- CustomEvent – לאירועים נדירים (שינוי משתמש, הוספה לעגלה). זה פשוט ואמין ללא תלות נוספת.
- EventBus – ללוגיקה מורכבת אנו משתמשים במחלקת EventEmitter קטנה המועברת דרך customProps.
תהליך ולוח זמנים
| שלב | משך |
|---|---|
| אנליטיקה – זיהוי מודולים הניתנים לבידוד, הגדרת גבולות microfrontend | 1–2 ימים |
| עיצוב – יצירת סכמת root-config, import map, הסכמה על פורמטי נתונים | 1–2 ימים |
| יישום – הגדרת orchestrator, כתיבת מתאמים לכל פריימוורק, חיבור CI/CD | 4–8 ימים |
| בדיקות – בדיקת הרכבה/פירוק, תאימות, זמן טעינה | 2–3 ימים |
| פריסה – פריסת root-config ו-microfrontends, שימוש ב-import map overrides למפתחים | 1–2 ימים |
ארכיטקטורה בסיסית עם root-config ו-2–3 microfrontends אורכת בדרך כלל 8–15 ימים. המחיר מחושב באופן אישי לפי מורכבות ומספר אפליקציות – עלות טיפוסית למערכת עם 3 microfrontends נעה בין $15,000 ל-$25,000. אנו מבטיחים ביצועים יציבים של המערכת בעומס של עד 10,000 RPS – הוכח בפרויקטים שלנו עם 5+ microfrontends.
למהנדסים שלנו יש ניסיון של 10+ שנים בפיתוח web והם מוסמכים ב-Single-SPA (גרסאות 5 ו-6). עזרנו ל-15+ חברות לעבור ל-microfrontends, תוך הפחתת זמן הפיתוח ב-30% בממוצע.
מה כלול בעבודה (פתרון turnkey)
- תיעוד של root-config ו-import map (תיאור ארכיטקטוני, סכמת אינטראקציה)
- מתאמים לכל microfrontend (React, Vue, Angular, Svelte)
- כיסוי בדיקות (בדיקות יחידה למחזור חיים, בדיקות e2e להרכבה)
- הכשרת צוות (סדנה על Single-SPA, שיטות עבודה מומלצות)
- 30 ימי תמיכה לאחר הפריסה
קבלו הערכה של הפרויקט שלכם. צרו קשר כדי לדון כיצד Single-SPA יכול להאיץ את הפיתוח שלכם ב-30% או יותר. אנו נעריך את הארכיטקטורה הקיימת שלכם ונציע את אסטרטגיית ה-microfrontend הטובה ביותר – בדרך כלל תוך יום עסקים אחד.







