הבלוג של ינון פרק

טיפים קצרים וחדשות למתכנתים

כתיבת קובץ לוג משרת Express באמצעות Winston

10/07/2021

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

המשך קריאה

איך לקרוא את כל התיעוד

09/07/2021

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

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

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

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

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

זה ריאקט? זה ויו? זה JSX בתוך Vue!

08/07/2021

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

export default {
  data() {
    return {
      value: 0
    };
  },

  methods: {
    inc(amount) {
      this.value += amount;
    }
  },

  render() {
    return (
      <div class="counter">
        <p>
          You clicked {this.value} times.
          <button onClick={this.inc.bind(null, 1)}>+1</button>
          <button onClick={this.inc.bind(null, -1)}>-1</button>
        </p>
      </div>
    );
  }
};

ואפשר לראות את מונה הלחיצות שלי בפעולה בקודסנדבוקס הבא: https://codesandbox.io/s/mystifying-leavitt-2iobe

הכתיב הזה בהחלט מרגיש בבית למתכנתי ריאקט. הכל פה חוץ מהשטויות של ריאקט, כלומר אנחנו כותבים class ולא className, ו for במקום htmlFor. בנוסף יש תמיכה גם ב Custom Directives של Vue, והכי מרגש שאפשר לכתוב את כל הקוד בקובץ js רגיל וכך לכתוב מספר קומפוננטות באותו קובץ. וכן למרות שהדוגמה שלי כאן היא מהכתיב הישן, גם Composition API תומך בסיפור הזה ומאפשר להחזיר JSX מ setup.

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

פרטים נוספים בתיעוד הקרוב אליכם בקישור: https://github.com/vuejs/jsx-next/tree/dev/packages/babel-plugin-jsx#readme.

מאוחר מדי

07/07/2021

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

קל לשאול "לאן נעלמה jQuery" או "מה קרה ל perl" ולתהות, האם קוברנטס עדיין יהיה רלוונטי בעוד חצי שנה? או React Native? ואפילו אם כן האם הם יהיו רלוונטיים באותו אופן, כלומר האם הגירסה שאני לומד עכשיו תהיה רלוונטית כשאני אגיע לרמה שאני יכול להשתמש בה כדי להרוויח?

אני חושב שהאמת קצת יותר מורכבת.

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

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

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

מרצפת שבורה

06/07/2021

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

הייתי צריך להיות יותר זהיר ...

הייתי צריך להתאמץ יותר ...

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

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

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

שלושים שעות עבודה ברצף הן לא הפיתרון

05/07/2021

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

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

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

המפתח שעוזר לנו להגיע להצלחה ולהרוויח טוב הוא ההבנה שהשוק מתגמל על מיומנות, ולפחות בתחום שלנו של פיתוח תוכנה, מתכנתת מיומנת תוכל להרוויח משמעותית יותר ממתכנתת פחות מיומנת או בתחילת הדרך - עד כדי פערים של פי 2, 3 או אפילו פי 5 לשעת עבודה. אם תשקיעו 60 שעות בשבוע בעבודה שמכניסה 100 ש"ח לשעה תרוויחו בכל חודש 27,000 ש"ח. לעומת זאת אם תשקיעו שנה שלמה בלימוד ושיפור מיומנות תוכלו למצוא עבודה ב 500 ש"ח לשעה ועכשיו ב 20 שעות עבודה בשבוע בלבד אתם מרוויחים 45,000 ש"ח בחודש.

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

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

תמונת סיום

04/07/2021

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

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

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

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

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

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

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

למה אני לא תמיד רושם מפתחות בלולאה ב React

03/07/2021

אחת מהודעות האזהרה שריאקט הכי אוהב להציג ב Console היא התלונה שלו על מפתחות:

Warning: Each child in a list should have a unique "key" prop. See https://reactjs.org/link/warning-keys for more information.

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

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

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

function ComponentWithWarning() {
    const items = [10, 20, 30];
    return (
        <ul>
            {items.map(i => <li>{i}</li>)}
        </ul>
    );
}

function ComponentWithoutWarning() {
    const items = [10, 20, 30];
    return (
        <ul>
            {items.map((i, index) => <li key={index}>{i}</li>)}
        </ul>
    );
}

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

כאן יש דוגמה לקוד ריאקט שבור שהבאג בו הוא היעדר מפתחות יציבים, ואין בו שום אזהרה בקונסול כי הוא משתמש באינדקס בתור מפתח: https://jsbin.com/wohima/edit?output

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

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

ולגבי האזהרה הרגילה של ריאקט? אני תמיד מעדיף אותה על פני כתיבת key={index} כי היא מזכירה לי שאין לי כרגע מפתח יציב ושאם ארצה להוסיף קוד שמשנה את סדר האלמנטים כדאי שאבחר קודם כזה מפתח.

איך להציג עץ ב React עם טבלה ו React.Fragment

02/07/2021

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

המשך קריאה

מייל חודשי אחרון

01/07/2021

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

המשך קריאה