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

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

היום למדתי: סדר המפתחות ב JSON.stringify

04/10/2021

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

const keys = ['a', 'b'];
const data = [ { a: 10, b: 20, c: 30 }, { a: 10, b: 20, c: 40 }, { a: 10, b: 12, c: 50 } ];

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

const groups1 = [ { a: 10, b: 20, c: 30 }, { a: 10, b: 20, c: 40 } ];

כי לשני האוביקטים בשדה a יש את הערך 10 ובשדה b יש את הערך 20, והקבוצה השניה תהיה האוביקט היחיד:

const group2 = [ { a: 10, b: 12, c: 50 } ];

כי השדה b מכיל בו ערך שונה - הערך 12.

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

// DO NOT USE - HAS A BIG BUG

const groups = _.groupBy(data, obj => JSON.stringify(_.pick(obj, keys)));

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

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

> JSON.stringify({ a: 10, b: 20 }, ['a', 'b'] )
'{"a":10,"b":20}'
> JSON.stringify({ a: 10, b: 20 }, ['b', 'a'] )
'{"b":20,"a":10}'
> JSON.stringify({ a: 10, b: 20 }, ['b'] )
'{"b":20}'

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

const groups = _.groupBy(data, obj => JSON.stringify(_.pick(obj, keys), keys));

שלושה טיפים לכתיבה טכנית שמשאירה רושם טוב

03/10/2021

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

המשך קריאה

תרגיל Bash - איך להזיז את כל המספרים בתיקיה

02/10/2021

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

01-hello
02-some-text
03-i-like-bash
04-zsh-is-ok-too
05-byebye

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

01-hello
03-i-like-bash
04-zsh-is-ok-too
05-byebye

כתבו סקריפט Bash שמתקן את הדילוג.

המשך קריאה

הזמן הכי טוב לשדרג

01/10/2021

הזמן הכי טוב לשדרג הוא אף פעם.

אבל הזמן הכי רע לשדרג הוא כשהכל קורס כי הסביבה שלך כבר לא נתמכת.

היום למדתי: פקודות שמתחילו ב git

30/09/2021

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

כל כך שמחתי לגלות את זה שיצרתי סקריפט בשם git-visit, נתתי לו הרשאות הרצה ושמרתי במקום נגיש בתוך ה PATH:

#!/bin/bash

xdg-open $(git remote -v | cut -d @ -f 2 | cut -d ' ' -f 1 | head -1 | sed 's/:/\//' | sed 's/.git$//' | sed s'/^/https:\/\//') >& /dev/null &

ועכשיו מכל תיקיה עם פרויקט גיט שמחובר לגיטהאב אפשר לכתוב:

$ git visit

ודף הפרויקט בגיטהאב ייפתח בדפדפן.

הטוב, הרע והמכוער עם Tailwind CSS

29/09/2021

טיילווינד סי אס אס הוא כנראה ספריית ה CSS הטרנדית ביותר כיום. אפשר לחשוב עליו כתגובת נגד לספריות כמו Antd ולדומיננטיות של JavaScript Frameworks: בגישה של antd אתה ממילא הולך להשתמש בפריימוורק אז הנה ספריית קונפוננטות שתתאים לכל פריימוורק שתבחר; בגישה של טיילווינד הנה דרך לכתוב CSS מודרני בלי JavaScript ולשתף את העבודה עם אחרים.

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

<div class="relative flex pb-5 space-x-5 border-b border-gray-200 lg:space-x-3 xl:space-x-5">
    <svg class="w-16 h-16 text-green-400 rounded-2xl" viewBox="0 0 150 150" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><rect x="0" y="0" width="150" height="150" rx="15"></rect></defs><g fill="none" fill-rule="evenodd"><mask fill="#fff"><use xlink:href="#plan1"></use></mask><use fill="currentColor" xlink:href="#plan1"></use><circle fill-opacity=".3" fill="#FFF" mask="url(#plan1)" cx="125" cy="25" r="50"></circle><path fill-opacity=".3" fill="#FFF" mask="url(#plan1)" d="M-33 83H67v100H-33z"></path></g></svg>
    <div class="relative flex flex-col items-start">
        <h3 class="text-xl font-bold">Basic Plan</h3>
        <p class="tracking-tight text-gray-500">
            <span class="text-sm transform inline-block -translate-y-2.5 relative">$</span>
            <span class="text-3xl font-bold text-gray-800">10</span>
            <span class="text-sm -translate-y-0.5 inline-block transform">/ user</span>
        </p>
    </div>
</div>

הקלאס border-gray-200 קובע את צבע הרקע לגוון מסוים של אפור והקלאס text-green-400 קובע את צבע הטקסט לגוון מסוים של ירוק. אתם מוזמנים לנסות לנחש מה אומר כל אחד מהקלאסים האחרים.

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

המשך קריאה

ולמה זה הגיוני לפתור את זה בשעתיים?

28/09/2021

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

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

אבל העולם האמיתי לא עובד ככה.

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

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

הזמנה לוובינר: בניית פרויקט צד-לקוח עם Vite

27/09/2021

פיתוח פרויקטי צד לקוח היה פעם הדבר הכי קל בעולם - יוצרים קובץ עם סיומת html, שומרים ופותחים בדפדפן.

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

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

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

הכלי vite שפיתוח Evan You (היוצר של vue) נועד לתת תבנית אחידה לבניית פרויקטים, לכל הפריימוורקים המרכזיים, ועם חווית מתכנת טובה יותר מזו שאנחנו מקבלים מכלים כמו create-react-app. הפרויקט קטן יותר, נבנה יותר מהר, שרת הפיתוח יהיה מהיר יותר ואותו הכלי יעזור לנו לבנות פרויקטים לריאקט, ל Vue, ל Svelte או לפרויקט ללא פריימוורק בכלל.

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

במהלך הוובינר אני מתכנן:

  1. להראות איך מתקינים את ויט על המכונה.

  2. להראות איך בונים פרויקטים בפריימוורקים המרכזיים.

  3. להראות מה מיוחד ב vite ומה הקסם שגורם לו לעבוד כל כך מהר.

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

  5. לענות על שאלות שלכם לגבי הכלי.

הוובינר יתקיים ביום חמישי הקרוב (ה 30.9) בשעה עשר בבוקר. תהיה הקלטה אבל יותר כיף להגיע ללייב כי אז אפשר לשאול שאלות ולהתפרץ. השתתפות בחינם והרישום בדף האירוע כאן: https://www.tocode.co.il/workshops/106

נתראה בחמישי ינון

האם Openbox הוא מנהל החלונות המושלם?

26/09/2021

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

המשך קריאה

דוקר: מה שלא צריך לדעת

25/09/2021

הקובץ הבא הוא קובץ Dockerfile תקין לגמרי שאני משתמש בו במצב פיתוח לפרויקט Node.JS:

FROM node:16

WORKDIR /app

הוא עובד אם מצמידים אליו קובץ docker-compose.yml שממפה את תיקיית הפרויקט לתיקיית /app על הקונטיינר, מגדיר את הפקודה להרצה ופותח את הפורטים המתאימים.

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

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

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

  1. חשוב להכיר את ה "מה" - מה זה אומר לרוץ בתוך קונטיינר, מה המגבלות של הקונטיינר.

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

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

  4. חשוב להבין איך נשמר מידע רגיש, מה זה Secrets ואיך לנהל אותם.

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

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

תכסו את ששת הסעיפים האלה ולאנשי ה Devops אצלכם יהיו חיים הרבה יותר קלים כשהם יבואו להפוך את קבצי ה Dockerfile הקטנים שתכתבו לקבצי הגדרות אמיתיים, ואת קבצי ה docker-compose.yml הקטנים שלכם להגדרות קוברנטס.