לעתים קרובות אנו נתקלים במצב הבא: צוות בוחר ב-Vite לצורך בנייה (bundling) אך אינו יכול להוסיף Module Federation — הפרוטוקול המקורי של Webpack 5 חסר. הפתרון קיים: הפלאגין @originjs/vite-plugin-federation (או vite-plugin-federation) מיישם את אותו פרוטוקול עם תמיכה בשני ה-bundlers. הניסיון שלנו מראה שהגדרה נכונה של remoteEntry ותלויות משותפות מפחיתה את זמן הטעינה ב-30% ומבטיחה פריסה עצמאית של מיקרוסרוויסים. כל remote ניתן לעדכון בנפרד ללא בנייה מחדש של ה-shell — קריטי לפרויקטים גדולים עם 5+ צוותים.
בעיה: בניות Webpack legacy האטו את הפיתוח — בניות dev ארכו 12 שניות. מעבר ל-Vite האיץ את האיטרציה לשנייה אחת. אבל Module Federation היה צריך להיות מוגדר ידנית, ומצאנו פתרון עובד. במאמר זה נסקור טעויות אופייניות בהגדרת תלויות משותפות, remotes דינמיים ותהליך הגדרת CI/CD. הזמינו הגדרה turnkey — אנו מיישמים microfrontends על Vite עם הבטחות ביצועים.
כבר פרסנו פתרון כזה עבור פלטפורמת מסחר אלקטרוני עם 12 מיקרוסרוויסים — זמן הטעינה ירד ב-40%. הצוות שלנו מוסמך ב-Vite ו-Module Federation. צרו קשר לייעוץ — נעצב את הארכיטקטורה האופטימלית.
למה Vite Module Federation עדיף על Webpack לפרויקטים גדולים
Vite מנצח במהירות הבנייה: במצב dev קומפילציה מצטברת אורכת ~200 אלפיות השנייה לעומת 2–4 שניות ב-Webpack. עם זאת, במצב dev יש לבנות remotes מראש (vite build --watch) ולשרת אותם דרך vite preview. זהו trade-off: מקריבים HMR עבור remotes אך מקבלים bundles ייצור קלים יותר.
נשווה פרמטרים מרכזיים:
| קריטריון | Vite + plugin-federation | Webpack 5 native |
|---|---|---|
| מהירות בניית dev | ~200 אלפיות השנייה (HMR עבור shell) | ~2–4 שניות (HMR עבור הכל) |
| טעינה חמה עבור remotes | לא (דורש בנייה מוקדמת) | כן |
| גודל bundle ייצור | קטן ב-15–20% | קו בסיס |
| הגדרה | פשוטה (פלאגין אחד) | מורכבת (ModuleFederationPlugin) |
| תמיכה ב-TypeScript | דרך טיפוסים נפרדים | מובנית |
אם מהירות הפיתוח וגודל ה-bundle קריטיים, לכו עם Vite. לאיטרציה מהירה בצוותים גדולים, אנו משלבים Vite עבור ה-shell ו-Webpack עבור remotes legacy. קבלו ייעוץ עם המהנדס שלנו כדי למצוא את הארכיטקטורה האופטימלית.
אילו תלויות משותפות צריכות להיות Singletons?
ב-Vite Module Federation, תלויות משותפות מוגדרות בדומה ל-Webpack. קריטי להגדיר singleton: true עבור ספריות עם state גלובלי: React, ReactDOM, MobX, Zustand. אחרת, כל remote טוען עותק משלו, מה שמוביל לשכפול bundle (עד +200 KB לכל remote) ולקונפליקטים בהקשר. דרישת הגרסה (requiredVersion) עוזרת למנוע אי-תאימות בעדכון חבילות.
דוגמת הגדרה:
// vite.config.ts (remote и host)
shared: {
react: {
requiredVersion: '^18.0.0',
singleton: true,
},
'react-dom': {
requiredVersion: '^18.0.0',
singleton: true,
},
'@company/shared-store': {
singleton: true,
requiredVersion: '*',
},
} דוגמת הגדרה עבור מספר remotes
// shell/vite.config.ts
federation({
name: 'shell',
remotes: {
catalog: 'https://catalog.example.com/assets/remoteEntry.js',
cart: 'https://cart.example.com/assets/remoteEntry.js',
},
shared: ['react', 'react-dom'],
}) איך להגדיר נכון תלויות משותפות: מדריך שלב-אחר-שלב
- זהו חבילות משותפות (ספריות UI, ניהול state, ניתוב).
- בכל remote ו-host, הוסיפו חבילות אלה ל-
// vite.config.ts (remote и host) shared: { react: { requiredVersion: '^18.0.0', singleton: true }, 'react-dom': { requiredVersion: '^18.0.0', singleton: true }, '@company/shared-store': { singleton: true, requiredVersion: '*' }, }עם// shell/vite.config.ts federation({ name: 'shell', remotes: { catalog: 'https://catalog.example.com/assets/remoteEntry.js', cart: 'https://cart.example.com/assets/remoteEntry.js', }, shared: ['react', 'react-dom'], })ו-shared. - ציינו התאמת גרסה מדויקת כדי למנוע אי-תאימות.
- בדקו במצב dev: הריצו remote עם
singleton: trueו-shell עם HMR רגיל. - בדקו בניית ייצור: ודאו שאין שכפול ב-bundles.
איך הקמנו Microfrontends: תהליך שלב-אחר-שלב
אנו עובדים turnkey — מארכיטקטורה ועד CI/CD. שלבים ולוחות זמנים:
| שלב | מה אנו עושים | לוח זמנים |
|---|---|---|
| ניתוח | הגדרת גבולות מיקרוסרוויס, תלויות משותפות, versioning | יום אחד |
| הגדרת remote | הגדרת requiredVersion עבור כל אפליקציה, הגדרת תלויות משותפות |
יומיים |
| הגדרת host | הגדרת shell, חיבור remotes, יישום תבנית Bootstrap עם Suspense ו-ErrorBoundary | יום אחד |
| אינטגרציה ובדיקות | אימות טעינת מודולי remote, טיפול בשגיאות, הרכבת remotes דינמיים | 1–2 ימים |
| CI/CD | הגדרת פריסה עצמאית לכל מיקרוסרוויס דרך GitHub Actions + CDN | יום אחד |
סה"כ 5–8 ימים. מספר ה-remotes משפיע על לוח הזמנים — כל אפליקציה נוספת מוסיפה 1–2 ימים.
מה כלול בעבודה
- תיעוד ארכיטקטוני: דיאגרמת אינטראקציה בין remotes, רשימת תלויות משותפות.
- הגדרת פלאגין לכל האפליקציות (remote ו-host).
- יישום תבנית Bootstrap עם טעינה דינמית של מודולי remote.
- הגדרת CI/CD (GitHub Actions, GitLab CI, או דומה) לפריסה עצמאית.
- בדיקות: אימות עומס, טיפול בשגיאות רשת, רכיבי fallback.
- הדרכת צוות: סדנה של 2 מפגשים על תחזוקת microfrontends.
- תמיכה טכנית למשך שבועיים לאחר המסירה.
צרו קשר להערכה מפורטת של הפרויקט שלכם — נכין הצעה מסחרית מותאמת לסטack ולדרישות שלכם.
טעויות נפוצות בהגדרת Vite Module Federation
- חסר
--watchעבור React: מוביל למספר עותקים ולשגיאת hooks. - נתיב remoteEntry שגוי: בעת פריסה ל-subdomain, הנתיב חייב להיות מוחלט (https://catalog.example.com/assets/remoteEntry.js).
- התעלמות מ-ErrorBoundary: אם remote לא זמין, כל האפליקציה קורסת. תמיד עטפו רכיבי lazy ב-
vite-plugin-federation. - חסר טיפוסי TypeScript: הפלאגין אינו מייצר declarations — פרסמו אותם כחבילת npm או השתמשו ב-
singleton: true.
איך להבטיח בטיחות טיפוסים בייבוא מודולי remote
הדרך האמינה ביותר היא לפרסם טיפוסים מה-remote כחבילת npm (@company/catalog-types). ב-host, ייבאו את הטיפוסים והשתמשו ב-<ErrorBoundary> עם טיפוסים:
import type { ProductListProps } from '@company/catalog-types';
const ProductList = React.lazy(() => import('catalog/ProductList')) as React.FC<ProductListProps>;חלופה היא כתיבת declarations ידנית ב-host, אך זה דורש סנכרון כאשר ה-API של ה-remote משתנה.
סיכום
Vite Module Federation הוא פתרון בוגר ל-microfrontends אם אתם מוכנים למוזרויות של מצב dev. הגדרה נכונה של תלויות משותפות, remotes דינמיים ו-CI/CD מספקים גמישות וביצועים. הזמינו הגדרה turnkey — נעצב ארכיטקטורה שמתרחבת ללא אובדן מהירות.







