הגדרת מונורפו: Turborepo, Nx או Bazel מקצה לקצה

בנייה ושחרור במאגר אחד נשברים כאשר מספר צוותים עובדים על המוצר: עריכות מפריעות זו לזו, והשחרורים מתעכבים. אנו מגדירים מונורפו מקצה לקצה — ממבנה הפרויקטים ועד לנהלי שחרור. הבנייה מפסיקה להיות צוואר בקבוק, ושחרור גרסה אורך דקות במקום שעות.

היכולות שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    776
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1022
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113

למה הגדרת מונורפוזיטורי נשברת כשהצוות גדל

בשנה הראשונה מאגר יחיד נראה כמו רווח: ענף אחד, סט בדיקות משותף, חבילות עושות שימוש חוזר בקוד זו של זו בלי לפרסם במרשם. עד הרגע שבו כמה צוותים עובדים עליו, השחרור נמתח מדקות לשעות, ותיקון במודול אחד בונה מחדש חצי מהמאגר.

העניין אינו בכלי הבנייה — החלפת בונה לא משנה את התמונה. המטמון מתבטל כולו, כי בשום מקום לא מתועד אילו חבילות תלויות במה: גרף הבנייה מתפשט בגלל קשרים לא מפורשים דרך מודולי עזר וטיפוסים משותפים.

יכולת השחזור של הבנייה נעלמת — מקומית המשימה עוברת, בסביבה המשותפת נופלת, ואת הסיבה מחפשים ידנית בלוגים.

בדיקות לכל קומיט אורכות שעות, כי מחשבות מחדש כל המטרות, ולא רק אלה שנגעו בהן. אף אחד לא מעז להריץ אותן בחלקים: בלי סכמת תלויות לא ברור מה באמת אפשר לא לבנות. זמן השחרור מפסיק להיות תלוי בהיקף התיקון ומתחיל להיות תלוי בגודל המאגר.

מעל זה מתווספים שלבים ידניים: סדר הפריסה של השירותים נשמר בראש של מהנדס אחד, גרסאות של חבילות משותפות נערכות ביד, ופער בין סביבות מתגלה רק בפרודקשן. נפרק איך זה נסגר באמצעות סכמת תלויות, גבולות מפורשים בין חבילות וביטול מטמון מדויק.

מה נותנת בנייה מסודרת: אפקטים מדידים

הגדרת מונורפוזיטורי נמדדת לא במספר החבילות, אלא בזמן שהצוות מבזבז על המתנה וטיפול בתקלות. את האפקטים שלמטה רואים במטריקות כבר בשבועות הראשונים.

זמן בנייה ובדיקות

גרף התלויות נבנה לפי קוד המקור, ולכן רק פרויקטים שנגעו בהם נבנים מחדש, והשאר מוחזר מהמטמון. שיעור הפגיעות במטמון בשינוי טיפוסי יוצא בטווח 70–90%, והרצה מלאה מפסיקה להיות ריטואל חובה לפני קומיט.

בדיקות רצות לפי אותו גרף: לינטרים, טיפוסים וטסטים מופעלים רק עבור חבילות שהשתנו והצרכנים שלהן. זמן הבדיקות יורד מעשרות דקות לדקות, והתור למיזוג מפסיק להיות צוואר בקבוק.

עלות זמן ההשבתה וסוגי כשל שנעלמו

המטמון קשור לתוכן ולסביבה: אם התצורה או גרסת הכלים משתנה — הוא מתבטל מעצמו, ולא מחזיר ארטיפקט מיושן. נעלם סוג הכשל «נבנה מקומית, נפל בענף המשותף».

הסוג השני שנעלם — חוסר סנכרון של ספריות משותפות: מרשם תלויות אחיד לכל מאגר לא נותן לשירותים להתפצל לגרסאות ראשיות לא תואמות. זמן ההשבתה כאן נמדד בשעות של צינור עיבוד חסום ובמספר האנשים שמחכים לטיפול.

מכאן האפקט החמישי: השחרור הופך לאירוע צפוי עם הרכב שינויים מובן, ותדירות השחרורים עולה בלי גידול בעבודה ידנית.

זו לא הסתמכות על ההערכה שלנו: Google מחזיקה את הקוד המרכזי במאגר אחד ומיישמת גרף בנייה משותף בקנה מידה של אלפי מהנדסים — אותה לוגיקה עובדת גם למטה, עד צוות של עשרה אנשים.

אפשרויות ארגון בנייה: השוואת גישות

אורקסטרטור בוחרים לפי גרף התלויות: כמה חבילות, בכמה שפות, באיזו תדירות משתנות ספריות משותפות. להלן ארבעה מצבי עבודה, כולל אפשרות בלי אורקסטרטור.

אפשרות מתי מתאימה מגבלות
אורקסטרטור ממשפחת Turborepo שפה אחת, עשרות חבילות, נדרשים מטמון מקומי ותצורה פשוטה בלי הכשרת הצוות כללי החשיפה של חבילות חלשים יותר, תרחישי בנייה לא סטנדרטיים משתלבים רע
Nx כמה אפליקציות וספריות משותפות, נדרשים גרף תלויות קפדני ואיסור ייבוא רוחבי סף כניסה גבוה יותר: צריך לתחזק את התצורה ולעבור עליה בסקירות
Bazel שפות רבות במאגר אחד, מטמון מרוחק ובנייה מבוזרת למאות חבילות ההגדרה נמדדת בשבועות, נדרש מהנדס ייעודי
בלי אורקסטרטור חבילה-שתיים, שחרורים נדירים, מחזור בנייה קצר אין מטמון מקומי: כל הרצה בונה הכול מחדש, הזמן גדל לינארית

איך לבחור מצב לפי גודל הצוות

לצוות קטן בדרך כלל מספיק אורקסטרטור ממשפחת Turborepo: מטמון מקומי מכסה בניות חוזרות, והתצורה נקראת כולה בערב אחד. כשיש עשרות חבילות וכמה אפליקציות, Nx מנצח — כללי החשיפה לא נותנים לאפליקציה לגרור פנימיות של ספרייה זרה, וגרף התלויות נשאר צפוי.

Bazel מוצדק כשהחבילות כתובות בשפות שונות והרצה בודדת נמשכת עשרות דקות: מטמון מרוחק ובנייה מבוזרת מחזירים דקות, אבל דורשים מהנדס שחי את הבנייה הזאת.

מעבר בין מצבים לא חייב להיות חד-פעמי: מתחילים בגרף ובמטמון מקומי, ומחברים מטמון מרוחק כשההרצה מפסיקה להיכנס לזמן נוח.

הגדרת מונורפוזיטורי: שלבי העבודה ההנדסית

את העבודה מובילים בשלבים: קודם מודדים, אחר כך משנים מבנה, ורק לאחר מכן נוגעים בבנייה ובבדיקות. מעבר למאגר אחד בלי מדידות הופך ללוטו עם שחרורים, ולכן כל החלטה אצלנו נשענת על נתונים לפני ואחרי.

אבחון וסכמת תלויות

  1. אבחון בנייה וגרף תלויות. מודדים בנייה מלאה ואינקרמנטלית, בודקים אילו חבילות גוררות אחריהן את כל המאגר, מחפשים מחזורים וקשרים לא מפורשים בין מודולים.
  2. גבולות חבילות. מסמנים מה הופך לחבילה עצמאית ומה לספרייה משותפת, וקובעים כללי ייבוא: אפליקציה לא נכנסת לפנימיות של מודול זר.
  3. תוכנית הטמעה. מעבירים את המאגר בחלקים — קודם אפליקציה אחת עם התלויות שלה, אחר כך את השאר, בלי לעצור שחרורים.

הגדרת בנייה ובדיקה

  • אורקסטרטור ומטמון. מגדירים Turborepo, Nx או Bazel לפי המבנה שהתקבל: מטמון לפי תוכן הקלטים ומטמון משותף לכל המכונות, כדי שמה שלא משתנה לא ייבנה מחדש.
  • פיצול משימות לפי פרויקטים שנגעו בהם. צינור הבדיקות מריץ טסטים ובנייה רק עבור חבילות שהשתנו ואלה שתלויות בהן — זמן הבדיקה מפסיק לגדול יחד עם המאגר.
  • בדיקה בתרחישים אמיתיים. מריצים שינויים טיפוסיים: תיקון בספרייה משותפת, שחרור, חזרה לאחור, ענפים במקביל. בנפרד מוודאים שהמטמון לא מחזיר תוצאה מיושנת.
  • קליטת התוצאה והעברה. משווים מדידות לפני ואחרי, מוסרים סכמת תלויות, כללי גבולות, תיעוד בנייה ומעבירים הכשרה לצוות.

מה מוסרים לידיים: תצורות, סכמות, נהלים

העברת מאגר היא מצב שצוות אחר משחזר בלי מחבר ההגדרה. כל ארטיפקט למטה מתאר לא «איך יצא», אלא למה נעשה דווקא כך ומה יישבר בשינוי.

תצורות וסכמות

  • תצורת בנייה ומטמון: קלטים ופלטים מפורשים של משימות, אזורי השפעה, כללי ביטול — הרצה חוזרת לא בונה מחדש חבילות שלא השתנו.
  • סכמת תלויות: גרף חבילות, גבולות מודולים, איסור קשרים מעגליים וייבוא בעקיפין לממשק הציבורי.
  • מדיניות גישה למטמון: הרשאות קריאה וכתיבה, תחום החשיפה של ארטיפקטים, תפקידים לענף השחרור ולקבלנים חיצוניים.
  • תיאור הסביבה המקומית: גרסאות מקובעות של הפלטפורמה ומנהל החבילות, הרמת המאגר בפקודה אחת, סט בדיקות לפני קומיט.

נהלים ותיעוד

  • נוהל הוספת פרויקט: קריטריונים להקצאת חבילה חדשה, תבנית התחלה, שדות תצורה חובה, סדר הסקירה.
  • עדכון תלויות וכלים: סדר בדיקת תאימות, קריטריון לחזרה לאחור, תדירות מיגרציות.
  • שחזור בנייה: נקודות כניסה, כשלי מטמון טיפוסיים, בנייה קרה מאפס, בדיקת שלמות ארטיפקטים.
  • קליטת מפתח: מסלול היום הראשון, פירוק שגיאות נפוצות, בעלי שירותים וסדר אסקלציה.

כל הארטיפקטים נמצאים במאגר לצד הקוד ומתעדכנים באותה סקירה שבה משתנה הבנייה — אחרת ההוראות מתנתקות מהמציאות תוך שבועיים.

מקרה בוחן: איך נעלם סוג כשל בבנייה ובשחרור

אלינו הגיע צוות משישה אגפי מוצר — יותר מארבעים מהנדסים במונורפוזיטורי אחד על כמה אפליקציות וספריות משותפות. הבנייה הופעלה כולה על כל שינוי: תיקון בחבילה עם טיפוסים משותפים גרר בנייה מחדש של כל המוצרים, הרצה מלאה ארכה כארבעים דקות, וההמתנה לסוכן בנייה פנוי הוסיפה עוד עד חצי שעה. המפתחים הפסיקו להריץ בדיקות מקומית, והשחרורים יצאו «על מזל».

המצב לפני

מטמון הבנייה היה מופעל פורמלית, אבל המפתח חושב לפי כל העץ בבת אחת, ולכן פגיעות כמעט לא קרו: שיעור הבניות החוזרות עמד על 12%, כלומר כמעט כל הרצה חושבה מאפס. כשלים הגיעו בשחרור, לא בבדיקה: כשליש מהשחרורים הוחזרו בגלל נפילת בנייה או גרסאות לא תואמות של חבילות משותפות. השורש לא היה בכלי אלא בסכמה — לחבילות לא היו גבולות מפורשים, והתלויות עברו דרך אפליקציות.

מה השתנה אחרי

פיצלנו את המונורפוזיטורי לשכבות — ספריות משותפות, חבילות דומיין, אפליקציות — וקבענו כללי תלויות: אפליקציה יכולה להיות תלויה בדומיין, דומיין בספרייה, וההפך אסור ונבדק אוטומטית.

את מפתח המטמון קשרנו לתוכן החבילה והתלויות שלה, ולכן ענפים שלא השתנו בגרף עושים שימוש חוזר בתוצאה מוכנה, ורק החלק שנגעו בו נבנה. צינור השחרור נבנה על Nx עם מטמון מרוחק משותף לכל הצוותים.

אחרי רבעון חזרו על המדידה במוצר שני והשוו למדידות פומביות של מונורפוזיטוריים גדולים — סדר הגודל תאם, כלומר התוצאה משוחזרת ולא הייתה מקרה של צוות אחד. זמן הבנייה המלאה הצטמצם מ-40 ל-7 דקות, שיעור הבניות החוזרות עלה מ-12 ל-78%, והכשלים בשחרור — מ-30 ל-3% ונשארים ברמה הזאת.

ספקות טכניים: תשובות קצרות למהנדסים

מונורפוזיטורי הוא לא «לקפל תיקיות למאגר אחד», אלא החלפת מודל עבודה: גרף תלויות אחיד, כללי בנייה משותפים, מטמון תוצאות משותף. להלן חמש שאלות שמובילים טכניים שואלים לרוב לפני תחילת מיגרציית מאגרים, ותשובות קצרות לעניין.

איך מועברת ההיסטוריה ממאגרים נפרדים?

ההיסטוריה נשמרת: מעבירים לא רק קבצים, אלא גם קומיטים עם מחברים, ענפים ותגי שחרור — ארכאולוגיה ו-blame נשארים עובדים. המאגרים מחוברים אחד-אחד, והישנים עד סוף המיגרציה חיים במצב קריאה בלבד, ולכן עבודה מקבילה של צוותים לא נעצרת.

האם זמן הבנייה יגדל אחרי האיחוד?

הוא גדל רק כשהתלויות בין חבילות מוצהרות לא נכון. כשהגרף מתואר ביושר, רק החלק שנגעו בו נבנה ונבדק מחדש, והשאר עולה מהמטמון לפי תוכן הקלטים. אם כלל יוצא רחב מדי, מצמצמים את אזורי ההשפעה של החבילות, ולא מוותרים על האיחוד.

איך מעבירים צוותים בלי לעצור שחרורים?

מעבר מדורג: קודם צוות חלוץ אחד מעביר את השירות שלו ומריץ את הכללים, אחר כך מצטרפים השאר. קוד חדש נכנס כבר למונורפוזיטורי, וענפים ישנים מסיימים את המחזור שלהם — המעבר לא שובר את לוח השחרורים.

איך מטמון משפיע על בדיקות חוזרות?

בדיקות חוזרות עושות שימוש חוזר בתוצאה אם קלטי המשימה לא השתנו — אותו סט טסטים לא רץ פעמיים על ענפים וסוכנים שונים. המטמון המרוחק משותף למכונות בנייה ולסביבות מקומיות, ולכן המפתח רואה תוצאה שכבר חושבה בשרת.

מי אחראי לכללי הבנייה אחרי העברת התמיכה?

הכללים חיים במאגר כקוד, לא בראש של מישהו: שינוי עובר סקירה, והבעלים של כל אזור מתועד. בהעברת תמיכה מוסרים תצורות, סכמת גרף תלויות, תיעוד לתיקונים טיפוסיים ומעבירים הכשרה לצוות.

נדבר על משימת הבנייה והשחרור שלכם

כדי לחזור עם הערכת היקף העבודה, ולא עם מילים כלליות, למהנדסים צריך מדגם של הבנייה הנוכחית שלכם. לפיו רואים איפה הזמן הולך לאיבוד: בהתקנת תלויות, בבנייה מחדש מלאה של חבילות בתיקון מודול אחד או בתיאום ידני של שחרורים בין צוותים.

נאסוף את המדגם הזה בשיחה אחת — מכם נתוני קלט ומדדי יעד, מאיתנו תוכנית הטמעה עם שלבים ונקודות חזרה לאחור.

  • סכמת המאגרים הנוכחית: מאגר משותף אחד, סט נפרדים או משולב; איך קשורות החבילות והספריות המשותפות.
  • צווארי בקבוק בבנייה: זמן בנייה מלאה ואינקרמנטלית, שיעור משימות שנכנסות למטמון, מה נבנה מחדש בלי שינויים.
  • הרכב הצוותים ותחומי אחריות: מי בעל החבילות, איך מתאמים תיקונים במודולים משותפים.
  • מגבלות לוחות שחרור: באיזו תדירות משחררים, האם יש חלונות שבהם אסור לעצור את הבנייה.
  • מדדי יעד: זמן בנייה ושחרור, שיעור מסלולים מכוסים בבדיקות, סוג כשל שצריך למנוע.
  • תשתית בנייה: היכן פועלים הסוכנים — מכונות משלכם, ענן או משולב, האם יש מגבלות גישה.
  • הכלי הנוכחי (Turborepo, Nx או Bazel) ומה בו הפסיק להתאים.

תארו את המשימה כפי שהיא עכשיו: קטעי תצורות, לוגים של בנייה או פשוט תיאור התהליך. נחזור עם הערכת היקף העבודה, תוכנית הטמעה ואפשרויות מעבר בלי לעצור שחרורים — נדון במשימה ונסתכם על הצעד הבא.

במה מאגר יחיד שונה מפרויקטים נפרדים?

בחירת מודל המאגרים היא לא עניין של נוחות למפתחים, אלא של האופן שבו שינויים רוחביים מתפשטים במערכת. כשמודול משותף נמצא במאגר נפרד, תיקון בו הופך לשרשרת שחרורים מתואמים: לעדכן חבילה, להמתין לבניות אצל כל הצרכנים, לסנכרן גרסאות. בעץ אחד אותו תיקון נבדק בבנייה אחת לפי גרף התלויות, ואי-התאמה צפה לפני הכניסה לענף הראשי.

אפשרות מתי מתאימה מגבלות
מאגר יחיד כמה מוצרים חולקים ספריות וחוזים, שינויים רוחביים קורים כל הזמן זמן בנייה ושיבוט גדל; נדרשים מטמון למשימות והפרדת הרשאות לפי תיקיות
פרויקטים נפרדים צוותים כמעט לא נפגשים בקוד וחיים במחזורי שחרור משלהם כל שינוי רוחבי הוא סדרת שחרורים; גרסאות של מודולים משותפים נפרדות בהדרגה
היברידי לפי דומיינים יש ליבה עם מודולים משותפים ומוצרים עצמאיים סביבה גבולות הדומיינים צריך לשמור ידנית, אחרת מתקבל אותו מונולית

בידוד צוותים נפתר לא במספר המאגרים, אלא בהרשאות גישה ובגבולות חבילות: בעץ אחד נותנים גישה לתיקייה, ותיקונים באזור זר נחסמים בבדיקות בזמן מיזוג. כלים כמו Turborepo, Nx או Bazel מוסיפים לעץ מטמון משימות וגרף תלויות — בלעדיהם בנייה של כל המאגר על כל שינוי הופכת לצוואר בקבוק.

המחיר של טעות בכללי בנייה משותפים הוא הגבוה ביותר: צעד כושל בעץ אחד עוצר בבת אחת את כל הצוותים, ולכן שומרים את הכללים לצד הקוד ומשנים אותם בשינוי נפרד שנבדק. אנחנו מתחילים במפת תלויות ובתדירות של תיקונים רוחביים — היא קובעת היכן עובר הגבול בין עץ משותף לפרויקטים נפרדים.