es
Feedback
ToCode

ToCode

Ir al canal en Telegram

טיפים קצרים למתכנתים מאת ינון פרק

Mostrar más
1 421
Suscriptores
+124 horas
Sin datos7 días
Sin datos30 días
Archivo de publicaciones
ToCode
1 421
# המדרגה הבאה אחת השאלות שהכי חשוב לשאול כשלומדים שפת תכנות היא "איך מישהי עם ניסיון בשפה זו היתה פותרת את הבעיה". אפשר לקרוא לשאלה הזו המדרגה הבאה. כי כשאנחנו באים ללמוד שפת תכנות חדשה כבר יש לנו בראש את ה if מ Java ואת ה class מ Python ובעצם כמעט כל מילה בשפה החדשה טעונה בכל מיני משמעויות מפעם, ולכן הפיתרון הראשון שאני חושב עליו לבעיה הוא פשוט יישום של הדברים שאני רגיל לכתוב משפה אחרת לתוך השפה החדשה. ולמה זה רע? בגלל ששפות שונות וסביבות שונות מתנהגות אחרת, בגלל שמבנה שיהיה יעיל במקום אחד עובד ממש רע במקום אחר. חוסר הידע וחוסר הניסיון בשפה החדשה אומר שאני עדיין לא רואה איך הדברים שאני כותב הולכים להישבר. כשרק התחלתי לכתוב ריילס שמחתי לגלות את ה ORM שלו והשתמשתי במחלקות שחזרו מבסיס הנתונים כאילו היו מחלקות רגילות מ Java. זה היה מאוד נפוץ לראות בקוד שלי לולאות מהסוג הזה:
users.map do |user|
    puts user.profile.nickname
end
כשהיום עם הניסיון שיש לי בריילס עומס הנקודות בשורה מיד מכניס אותי למתח. בלימוד שפה חדשה האתגר הוא לא לכתוב קוד שעובד. הרבה יותר חשוב לכתוב קוד שמתאים ל Ecosystem שאת באה ללמוד.

ToCode
1 421
# איך לפתוח בלוג ג'קיל ולאחסן אותו בחינם על גיטהאב ערן העביר היום וובינר על ג'קיל והזכיר לי כמה כיף לפתוח בלוגים. אחרי הוובינר המשכתי לשחק עם הכלי עד שהצלחתי לשים משהו באוויר וזה נראה כך: https://ynonp.github.io/ynonlearnsrussian/ בשביל שיהיה קל לשחזר את ההישג עם בלוגים עתידיים שארצה או שאתם תרצו לפתוח, אני מסכם כאן את הצעדים המרכזיים ביצירת ופתיחת בלוג ואחסונו אונליין בחינם על גיטהאב. ## התקנת הכלים בגדול תצטרכו את ג'קיל על מכונת הפיתוח שלכם. ג'קיל הוא ג'ם לרובי לכן בהנחה שיש לכם רובי מספיק להפעיל פעם אחת:
gem install jekyll
ואתם מסודרים. ## יצירת שלד לפרויקט הפקודה jekyll new יוצרת בלוג חדש עם מבנה תיקיות יחסית מינימליסטי של ג'קיל:
$ jekyll new <blogname>
אחרי היצירה תוכלו להיכנס לבלוג, לעדכן את הקובץ about.markdown בשביל לשנות את מסך ה"אודות" או את הקובץ index.markdown בשביל לשנות את הדף הראשי. מה שיותר מעניין יהיה שתוכלו ליצור פוסטים באמצעות הוספת קבצים לתיקיית _posts. כל פוסט הוא קובץ ששמו מתחיל בתאריך ולאחר מכן slug, לדוגמא בבלוג שלי הפוסט היחיד שמור בקובץ בשם 2019-10-31-welcome-to-jekyll.markdown. תוכן הקובץ כתוב ב markdown ואחרי שתכנסו לקובץ הדוגמא שג'קיל יצר תראו שזה ממש פשוט לקרוא ולכתוב כאלה. אחרי שכל השינויים במקום תוכלו להפעיל:
$ jekyll serve
ולקבל שרת מקומי שרץ על localhost:4000 עם הבלוג שלכם. ## שינוי הקבצים והתאמת העיצוב הבעיה הראשונה שנתקלתי בה אחרי יצירת הבלוג היא שרציתי לשנות את העיצוב בשביל העברית (ובכלל בשביל החיים). ג'קיל שומר את כל קבצי העיצוב כחלק מה Theme וכברירת המחדל לא מייצר לכם את הקבצים האלה בתיקיית הפרויקט. זה אומר שבשביל לשנות אותם נצטרך קודם לקחת אותם מה Theme אלינו ורק אז נוכל לעדכן. ערכת נושא ברירת המחדל נקראת minima. הפקודה הבאה מציגה איפה על המחשב שלכם היא מותקנת:
$ bundle show minima
אצלי התוצאה היא:
/Users/ynonperek/.rvm/gems/ruby-2.6.3/gems/minima-2.5.1
נכנסתי לתיקיה ולקחתי את כל הקבצים ממנה לתיקית הפרויקט. אם אתם על לינוקס או מק מספיק להריץ את הפקודה הבאה מתוך תיקיית הבלוג הראשית:
$ cp -R $(bundle show minima)/* .
עכשיו יש לנו כבר המון קבצים בבלוג ואפשר להתאים אותם לצרכים שלנו, לדוגמא ה CSS ישב בקובץ assets/main.scss. ## העלאה לגיטהאב החלק המסובך הראשון הוא להעלות את הבלוג שלכם לגיטהאב. השתמשתי במנגנון שנקרא Github Pages שעובד כך: 1. אנחנו יוצרים פרויקט גיטהאב חדש ובו ענף חדש בשם gh-pages. 2. אנחנו מחברים את הבלוג שלנו לענף gh-pages בפרויקט. 3. אנחנו מעדכנים את הבלוג כך שיגיש את כל הנכסים עם ה base הנכון. 4. אנחנו גולשים לכתובת מיוחדת של github pages כדי לראות את הבלוג. אני מניח שאתם יודעים ליצור פרויקט גיטהאב חדש (לא יודעים? יש קורס גיט מעולה כאן באתר). אחרי שיצרתם והעליתם את הענף תוכלו להיכנס להגדרות הפרויקט ולגלול למטה, ושם תמצאו קטע שנקרא GitHub Pages בתוכו תמצאו את ה URL לאתר שלכם. אנחנו צריכים לקחת את ה URL הזה בתור base ב html. בשביל זה נכנס לקובץ _includes/head.html ושם נוסיף את האלמנט:
 <base href="{{ site.baseurl }}/">
בנוסף בקובץ _config.yml מהתיקיה הראשית של הבלוג נרשום בשדה url את הדומיין דרך גיטהאב בו הבלוג נמצא (אצלי זה https://ynonp.github.io/) ובשדה baseurl נרשום את הנתיב לבלוג, שזה שם הפרויקט (אצלי זה "/ynonlearnsrussian"). שמירה ודחיפה ואם עשיתם הכל נכון תוכלו להנות מהבלוג שלכם בכתובת בה גיטהאב מפרסמים אותו. הקוד המלא לבלוג שלי נמצא כאן למקרה שפספסתם משהו מהסבר הטקסט או שתרצו לקבל עוד רעיונות: https://github.com/ynonp/ynonlearnsrussian/tree/gh-pages

ToCode
1 421
# תיאום ציפיות כשאתם באים לקנות מכונים יש המון אופציות מהן אפשר לבחור ויש כמה דברים ברורים - אם בחרתם לקנות רכב חדש אתם יודעים שתהיה ירידת ערך בשנים הראשונות, אם הלכתם על יד שניה אתם יודעים שתשלמו קצת פחות אבל לא תקבלו את הרכב עם כל הניילונים ואם הלכתם על רכב קצת יותר ישן (הבחירה האהובה עליי) אתם יודעים שתשלמו פחות מראש אבל תבלו יותר זמן במוסך. בתוך המערכת הזאת אנחנו יכולים להיות מופתעים לטובה או לרעה - אם קנינו רכב ישן וכבר שנתיים שהוא לא ראה מוסך אנחנו מופתעים לטובה. אם קנינו רכב חדש ואחרי חודש דברים מתחילים להישבר אנחנו מופתעים לרעה ומתעצבנים. המשחק של תיאום ציפיות בתור פרילאנסרים אינו שונה בהרבה: 1. אם את הפרילאנסרית שיודעת לפתור בדיוק את הבעיה שאני צריך ובצורה הטובה ביותר, יהיו לקוחות שישמחו לשלם אקסטרה, בדיוק כמו שיש אנשים שאוהבים לקנות רכב חדש. רק זכרי שבמחיר הזה הפרויקט חייב לעבוד מעולה ולהקדים את לוחות הזמנים. 2. או, אם את מוכנה לעבוד בזול בשביל לצבור ניסיון, יהיו בהחלט לקוחות שישמחו לקחת את הסיכון ואפילו יתנו לך מרחב תמרון כדי לבנות את הפרויקט בדרך שלך. הם ממילא לא שילמו הרבה וישמחו להיות מופתעים לטובה. המצב היחיד שאני חושב ששווה להיזהר ממנו הוא האמצע - רכב בן 3 שכמובן עולה הרבה פחות מרכב חדש אבל עדיין עובד טוב ולא מגיע למוסך. בתור צרכן זה הדיל הכי טוב שאפשר לקבל, הבעיה שבתור הרכב (או הפרילאנסר במקרה שלנו), זה דיל שמאוד קשה להצליח בו: התחרות קשה מכל הכיוונים, את לא גובה מספיק בשביל שתוכלי לתת את האקסטרה ולהפתיע לטובה ולכן הרבה פעמים הסיפור הזה נגמר רע.

ToCode
1 421
# ביטול מחיקה בריילס (כמו בג'ימייל) מכירים את הכפתור Undo שמופיע בג'ימייל אחרי שמחקתם הודעה? עם הטכנולוגיה של היום לא חייבים להיות מהנדסת בגוגל בשביל לבנות דבר כזה גם למערכת שלכם. הנה מדריך קצר למימוש בריילס. ## בגדול - איך זה עובד לא יודע מה גוגל עשו אבל דרך פשוטה לבנות כזה מנגנון מורכבת ממספר שלבים: 1. הכי חשוב לא באמת למחוק את ההודעות, אלא רק לעשות כאילו. לכן ניצור עמודה ב DB בשם archived והודעות שנמחקו יסומנו בתור true בעמודה זו. 2. כל פעם שאנחנו "מוחקים" הודעה צריך לזכור מזהה של פעולת המחיקה, כדי שאפשר יהיה לבטל את מחיקת כל ההודעות במכה אחת. נוסיף לכן עמודה נוספת בשם recover_token שתכיל מזהה אקראי ממש. 3. ברגע שמשתמש מוחק הודעה אנחנו נעביר את ההודעה לארכיון ונגריל מזהה אקראי ממש עבור recovery_token. בדף האינדקס החוזר נשלח את המזהה הזה. משתמש יוכל לפנות לנתיב חדש (נקרא לו recover) בצירוף המזהה האקראי וכך לשחזר את ההודעות שבטעות מחק, מה שנקרא Undo. קוד? יאללה קוד. ## פעולת המחיקה המרובה ב Controller נתחיל עם מחיקה מרובה. משתמש שמגיע לכאן סימן מספר הודעות דרך פרמטר message_ids והפונקציה צריכה להעביר את כל ההודעות לארכיון. בשביל לאפשר undo הפונקציה תגריל ותשמור גם את ה token:
  def destroy_multiple
    recover_token = SecureRandom.hex(25)
    Message.where(id: params[:message_ids]).update_all(archived: true, recover_token: recover_token)

    flash[:recover_token] = recover_token
    redirect_to messages_path
  end
## פעולת שחזור לפי Token אחרי מחיקה מוצלחת אנחנו רוצים לאפשר גם שחזור (או undo). בואו נניח שמשתמש מגיע עם טוקן, אז כל מה שצריך לעשות זה למצוא את ההודעות שקשורות לטוקן הזה ולהחזיר אותן לחיים. הקוד נראה כך:
  def recover
    recover_token = params[:token]
    Message.where(recover_token: recover_token).update_all(archived: false)
    redirect_to messages_path
  end
## חיבור הפעולות לנתיבים בקובץ config/routes.rb נרצה לחבר את שתי הפעולות החדשות שלנו ל Controller. את הפרויקט לדוגמא התחלתי עם Scaffold כך שהקובץ יחסית ריק, הנה הוא עם התוספת:
Rails.application.routes.draw do
  resources :messages do
    collection do
      delete 'destroy_multiple'
      post 'recover'
    end
  end
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
## הצגת הקישור על הדף ולסיום דף רשימת ההודעות שצריך עכשיו לכלול את הקישור המיוחד. אם תגללו למעלה תוכלו לראות ששמרתי את הקישור ב flash, ולכן הוא זמין לדף האינדקס. אם קיבלנו טוקן כזה בדף האינדקס נציג את הקישור באופן הבא:
  <% if undo_token = flash[:recover_token] %>
    Messages were deleted. 
    <%= link_to('undo ?', recover_messages_path(token: undo_token), method: :post) %>
  <% end %>
## מחשבות לעתיד הקוד עדיין לא גנרי ויהיה קשה להשתמש בו על עוד מודלים במערכת. כנראה שעדיף להוסיף במודל פונקציית מחיקה בטוחה ולקרוא לה מה Controller, ואז אפילו להוציא אותה ל Concern כדי שאפשר יהיה להשתמש בה בעוד מודלים. בעולם עוד יותר יפה היינו שומרים States של המודלים שלנו בטבלא נפרדת ומנהלים את הכל מחוץ למודלים, וכך יכולים לטפל גם ב Undo לשינוי ולא רק למחיקה. זה מה שעושה הג'ם ממנטו. העליתי אגב לגיטהאב את פרויקט הדוגמא אז אם יש חלקים בקוד שמעניינים אתכם ושכחתי להדביק כאן מוזמנים להעיף מבט בקישור https://github.com/ynonp/undo-demo

ToCode
1 421
# מתכנתים שאני רוצה לעבוד איתם מקריאה במודעות דרושים נראה לפעמים שכולם מחפשים נינג'ות או תותחים או סופרסטארים או מה שלא יהיה, וזו טרמינולוגיה קצת מלחיצה. רוב האנשים לא יגדירו את עצמם בתור נינג'ות ובינינו אני לא בטוח שהייתי רוצה לעבוד עם אלה שכן. ובכל זאת אנחנו יודעים שיש מתכנתים ומתכנתות שמצליחים תמיד למצוא עבודה גם בטכנולוגיה שאף פעם לא נגעו בה, ויש כאלה שגם אחרי 5 שנים ניסיון עדיין יתקשו להחזיק במשרה. אז כן אני חושב שאנחנו צריכים שם אחר בשביל האנשים האלה שאנחנו רוצים לעבוד איתם, אבל את התכונות שלהם יחסית קל לזהות: ## להתעקש למצוא פיתרונות אני תמיד מעדיף לעבוד עם אנשים שמוצאים את הדרך לפיתרון, גם כשהפיתרון הברור לא עובד. התשובה "כתבתי את זה ככה כי זה מה שעבד" הרבה יותר טובה מ"ויתרתי על הפיצ'ר כי לא הצלחתי לגרום לו לעבוד". ## זה לא המחשב, זה אתה מתכנתים טובים אף פעם לא יאשימו את המחשב, כי הם יודעים שהבעיה האמיתית היא במי שכותב את הקוד. כבר לפני עשר שנים פירסם ג'ף אטווד מאמר מעולה עם הכותרת הכלל הראשון של תכנות: זו תמיד אשמתך, והוא צודק כמובן. למתכנתים טובים אין בעיה לצלול לפינות הכי אפלות של הקוד כדי למצוא מה שבור, ולמה מנגנון מסוים לא עובד כמו שכתוב בהוראות. ## לדעת לתת לפני שלוקחים מתכנתים טובים ישלחו Pull Requests לפרויקטים בהם השתמשו מגיטהאב כשצריך לתקן, יפתחו Issue כשצריך לפתוח אחד ומבלים חלק משמעותי מהזמן שלהם בלעזור למתכנתים אחרים. ולא, לעזור לאחרים זה לא לפתור להם את הבעיות - לעזור לאחרים זה להראות להם את הבעיות. מתכנתים טובים יודעים שכשהאנשים שסביבם ידעו לראות בעיות בצורה טובה יותר כולם ירוויחו, ושגם ההצלחות שלנו מגיעות במידה רבה בזכות הקהילה והאנשים שעזרו ועוזרים לנו לאורך הדרך. זאת הסיבה שהדבר הראשון שאני מסתכל עליו בפרויקט Github של מתכנת יהיה איזה Pull Requests הוא שלח ואיזה מהם התקבלו, הרבה לפני שאסתכל על פרויקטי הצד והקוד שאותו מתכנת כתב. ## להתאמץ למצוא את הדרך הקלה לארי וול כתב פעם על שלושת התכונות החשובות ביותר למתכנתים שהן: עצלנות, חוסר סבלנות והיבריס. שילוב של כל השלוש הוא שדוחף אותנו להתאמץ למצוא את הדרך הקלה אפילו כשממש לא ברור מהי, ובדרך לכתוב פיתרונות יצירתיים וחדשניים לבעיות. מתכנתים שאני רוצה לעבוד איתם יעבדו מאוד קשה בשביל לכתוב תוכניות שחוסכות להם זמן, פשוט כי הם מתעצלים לעשות את אותה עבודה שגרתית שוב ושוב. ## ללמוד מכל מי שאפשר מכל האנשים אלה שהכי מלחיצים אותי הם אלה שחושבים שהם כבר יודעים הכל וכבר ראו הכל. כשאני שומע מתכנת אומר לי שכל שפות התכנות הן אותו דבר, או שאחרי שכתבת כמה אפליקציות אתה כבר מבין איך דברים עובדים, אני מחייך ובורח. המתכנתים שאני רוצה לעבוד איתם יחפשו תמיד את הדבר השונה, החדש, את הדבר הנוסף שאפשר ללמוד - מהפרויקט, משפת התכנות או מהחברים לצוות.

ToCode
1 421
# מישלב אתר מילוג מגדיר את המילה מישלב בתור ״רמה לשונית בהתאם לסיטואציה או למעמד החברתי״. שווה לזכור שגם כשאתם כותבים וקוראים קוד יש משמעות למישלב, יש תבניות מסוימות שאופייניות לקבוצות מתכנתים מסוימות ואחרות שמאפיינות קבוצות אחרות. המישלב הוא שמאפשר לי לדעת המון על מתכנת או מתכנתת רק מלקרוא קטע קצר של קוד שהם כתבו. ההבדל בין שתי הפונקציות הבאות הוא תהומי, למרות ששתיהן כתובות באותה שפה ועושות בדיוק את אותו דבר:
function ReturnFirstElement(array) {  
  if (array.length > 0) {
    var result = array[0];
  }
  else {
    var result = undefined;
  }
  return result;
}

const returnFirstElement = (arr) => arr[0];
ואני לא רוצה להתחיל בכלל לדבר על ההבדל בין שתי הפונקציות האלה:
function fib1(n) {
  let [x, y] = [0, 1];
  for (let i=0; i < n; i++) {
    [x, y] = [y, x + y];
  }

  return x;
}

function fib2(n) {
  let [x, y] = [0, 1]
  for (let i=0; i < n; i++) {
    [x, y] = [y, x + y]
  }

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

ToCode
1 421
# למה ואיך לפתוח בלוג מקצועי בלוג מקצועי הוא כלי עבודה מאוד חשוב למתכנתים היום, ולפחות בשבילי הכתיבה בבלוג זה משהו שאני מחכה לו במהלך היום. לפעמים זה בעקבות התמודדות עם תקלה מעניינת, לפעמים אחרי שלמדתי משהו חדש ולפעמים בעקבות תובנה לגבי המשך הקריירה. בלוג מקצועי (לפחות בשבילי) מספק שלושה כיווני התפתחות בריאים לקריירה: 1. בלוג עוזר לסדר את המחשבות - אחרי התמודדות עם באג או בעיה תכנותית מעניינת התשובה הראשונה שאני מגיע אליה היא הרבה פעמים לא הטובה ביותר. כן, אני מצליח להגיע לקוד שעובד, אבל רק אחרי שאני מנסה להסביר לעצמי ולכם למה הקוד הזה עבד אני מבין שבעצם פספסתי כמה נקודות חשובות או כמה מקרי קצה, ואז אני חוזר לשולחן השרטוטים כדי לתקן את הפיתרון. הכתיבה על הבעיה פותחת אותה מחדש ונותנת הזדמנות לחשוב שוב על הפיתרון ולנסות לשפר. פוסט שמדבר על פיתרון מסוים גם עושה חשק לחפש את הפיתרון הטוב ביותר שאני יכול לבעיה. 2. בלוג עוזר לאחרים להכיר אתכם - בפוסט יחסית חדש מהבלוג מאיה כותבת אלגוריתמים מספר מאיה איך התחילה לקבל הצעות עבודה מעולות אחרי פירסום של הבלוג שלה בלינקדאין. אני לגמרי מזדהה. היום מסמך קורות חיים כמעט לא אומר כלום על הבן אדם, כי כולם כותבים קורות חיים מפוצצים. בלוג טוב לעומת זאת זה סיפור אחר לגמרי. בלוג נותן לך הזדמנות להסביר דברים לעומק ולאחרים (שמתעניינים) באותם דברים הזדמנות לקרוא ולהתעמק בפיתרונות. אחרי שקוראים את הבלוג של מאיה אפשר לקבל את הרושם כאילו ישבתם איתה לפתור יחד בעיה טכנית (או 10). בלוגים מקצועיים רבים שאני קורא נותנים את ההרגשה הזו וזה כמובן דבר שפותח הרבה דלתות. 3. בלוג עושה חשק לנסות דברים חדשים - מכירים את המחשבה הזאת של "מעניין איך מנגנון כזה וכזה עובד?" שבאה ואז נעלמת? ובכן אם יש לכם בלוג אתם רק מחכים למחשבות כאלה וממש לא נותנים להן לברוח. מחשבה כמו "מעניין איך כותבים פותר סודוקו" הופכת לחומר הגלם ממנו אתם מייצרים את הפוסט הבא, וכך פוסט אחרי פוסט אתם מנסים יותר דברים וכך לומדים בעצמכם יותר. ואם שכנעתי אתכם לפתוח בלוג אז כל מה שנשאר זה להראות איך, ובשביל זה הזמנתי ליום חמישי את ערן גולדמן-מלכא להעביר וובינר של שעה על כלי נפלא שנקרא Jekyll. ג'קיל הוא כלי קוד פתוח שאם הייתי צריך לבחור היום הייתי בטוח בוחר בו כדי לפתוח את הבלוג שלי: ההתקנה קלה, הוא מאוד ידידותי למתכנתים וכל הבלוג נשמר בלי צד שרת ורק עם דפים סטטיים. אז אם יש לכם שעה פנויה בחמישי בבוקר, ואחרי זה עוד כמה שעות בשבוע כדי אשכרה לכתוב בבלוג, מוזמנים להצטרף אלינו בקישור: https://www.tocode.co.il/workshops/88 נ.ב. אם יש לכם כבר בלוג ורוצים לשתף ממש אשמח לקישור בתגובות (עדיף אחד שאפשר לקרוא ברסס).

ToCode
1 421
# היום למדתי: התקנת חבילות אופליין עם Node.JS כשהמקום בדיסק הקשיח שלי מתחיל להיגמר אני עובר עם זכוכית מגדלת על כל הקבצים והתיקיות ומחפש מה אפשר למחוק, כי בתחושה שלי דיסק קשיח של חצי טרה צריך להספיק לפחות לכל החיים. בכל מקרה בתוך החיפוש מצאתי ספריה קטנה בתיקיית הבית שנקראת ~/.npm שתופסת לי היום קצת מעל ג'יגה. מה שיותר מפתיע היה תוכן התיקיה: היא מכילה את כל החבילות שאי פעם התקנתי ובכל הגירסאות שלהן. זה כאילו מישהו לקח את כל תיקיות ה node_modules של העולם והדביק את הכל יחד לתוך תיקיה אחת. אז הלכתי לתיעוד ומסתבר שזה בדיוק מה ש npm עושה כל פעם שאנחנו מתקינים חבילה. עוד קצת חיטוט בתיעוד ומסתבר שאפשר להשתמש ב cache הזה כדי להפוך את ההתקנות שלכם להרבה יותר מהירות. העברת הדגל --offline ל npm install גורמת ל npm להתקין את הספריה מהמטמון המקומי בלי לבקר באינטרנט כלל. הנה השוואת זמנים קטנה בשביל לעשות גם לכם חשק:
$ time npm install --save express
real 0m3.625s

$ time npm install --offline --save express
real 0m1.646s
עכשיו רק נשאר למצוא איך להגביל את גודל ספריית ~/.npm כדי שלא תתפוס לי את כל הדיסק.

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

ToCode
1 421
# טיפ וובפאק: הדרך הכי קלה להבין איך וובפאק בונה את הבאנדל שלכם אחד האתגרים בפיענוח ופירוק באנדלים גדולים הוא להבין איזה מודולים נכנסו לבאנדל ולמה וובפאק בחר להכניס כל אחד מהם. שני דגלים של וובפאק שאני מאוד אוהב הופכים את האתגר הזה לממש פשוט: הדגל display-modules מציג את כל המודולים שוובפאק הכניס לבאנדל, והדגל display-reasons מציג את הסיבות. בהפעלה לדוגמא זה נראה כך:
localhost:after ynonperek$ npx webpack --display-reasons
Hash: 1a41b54711f73da75381
Version: webpack 4.39.2
Time: 387ms
Built at: 10/23/2019 9:02:26 PM
 Asset      Size  Chunks             Chunk Names
app.js  1.16 KiB       0  [emitted]  main
Entrypoint main = app.js
[0] ./src/main.js + 1 modules 387 bytes {0} [built]
    single entry ./src/main.js  main
    | ./src/main.js 58 bytes [built]
    |     single entry ./src/main.js  main
    | ./src/panel.js 329 bytes [built]
    |     harmony side effect evaluation ./panel  ./src/main.js 1:0-28
    |     harmony import specifier ./panel  ./src/main.js 3:0-5
הבאנדל כולל נקודת כניסה אחת בשם ./src/main.js שמורכבת משני קבצים: הקובץ main.js הוא נקודת הכניסה, והקובץ panel.js שיובא באמצעות import מתוך main.js. יותר מזה - אנחנו רואים ששורה 1 בקובץ main.js היא שהפעילה את ה import (בגלל ההודעה harmony side effect evaluation שנמצאת לידה), ובשורה 3 בקובץ main.js יש קריאה לפונקציה מתוך הקובץ panel המיובא. עם האינפורמציה מול העיניים אני יכול להתחיל את האופטימיזציות - איזה קבצים גדולים מדי יש לי בבאנדל? האם אפשר להוציא חלק מהם לטעינה ב ajax? ואיזה מודולים נכנסו לבאנדל למרות שהייתי בטוח שכבר מחקתי אותם?