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

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

זהירות: מאפייני CSS שעוברים בירושה

08/10/2021

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

<script setup>
</script>

<template>
  <div>
    <h1>Hello World</h1>
  </div>
</template>

<style scoped>
h1 {
  color: blue;
}
</style>

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

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

<script setup>
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld msg="Hello Vue 3 + Vite" />
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

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

אם נסתכל בכלי הפיתוח של הדפדפן ב Inspect Element על ה h1 אנחנו נראה ברשימת כל כללי העיצוב שחלים עליו את הבלוק של #app עם כל הכללים הרלוונטיים:

    font-family: Avenir, Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
}

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

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

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

  • border-collapse
  • border-spacing
  • caption-side
  • color
  • cursor
  • direction
  • empty-cells
  • font-family
  • font-size
  • font-style
  • font-variant
  • font-weight
  • font-size-adjust
  • font-stretch
  • font
  • letter-spacing
  • line-height
  • list-style-image
  • list-style-position
  • list-style-type
  • list-style
  • orphans
  • quotes
  • tab-size
  • text-align
  • text-align-last
  • text-decoration-color
  • text-indent
  • text-justify
  • text-shadow
  • text-transform
  • visibility
  • white-space
  • widows
  • word-break
  • word-spacing
  • word-wrap

אני עובד על הפרויקט הזה כדי-

07/10/2021

אני עובד על הפרויקט -הזה- כדי לשלם את החשבונות

כדי להישאר בחזית הטכנולוגיה

בשביל ההזדמנות לעבוד עם האנשים האחרים בצוות

כדי לכתוב "גוגל" בקורות חיים

כדי שיהיה לי משהו מלהיב לספר במסיבות

כדי ללמוד טכנולוגיה ספציפית שאני חושב שתהיה מאוד מצליחה

כדי להציל את כדור הארץ

כדי לקדם אג'נדה שחשובה לי

כדי להתעשר

כדי לטייל בעולם

כדי לרשום פטנטים

כדי להתפרסם

כדי ללמוד איך עובד סטארטאפ ובעתיד לפתוח אחד משלי

כדי ליצור קשרים איכותיים בתעשיה


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

לדעת איך להתרסק

06/10/2021

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

import random

x = random.randint(0, 10)
y = random.randint(0, 10)

print("{} + {} = ?".format(x, y))
guess = int(input())

if x + y == guess:
    print("Bravo!")
else:
    print("Better luck next time...")

קל לראות שיש בתוכנית בעיה - אם משתמש כותב במילים את התשובה במקום לכתוב את המספר התוכנית תתרסק:

7 + 0 = ?
seven
Traceback (most recent call last):
  File "/home/ynon/tmp/blog/error1.py", line 7, in <module>
    guess = int(input())
ValueError: invalid literal for int() with base 10: 'seven'

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

$ python2 error.py

10 + 10 = ?
__import__('os').mkdir('yay')
Traceback (most recent call last):
  File "error1.py", line 7, in <module>
    guess = int(input())
TypeError: int() argument must be a string or a number, not 'NoneType'

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

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

05/10/2021

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

ביום חמישי הקרוב אדבר על Vue.JS בוובינר שמיועד למתכנתי ווב שלא ראו עדיין את הפריימוורק ואפילו יתאים אם ביליתם את השנים האחרונות במערה ולא ראיתם אף JavaScript Framework מודרני. אראה לכם איך לפתוח פרויקט Vue מההתחלה ואיך לשלב Vue בתוך פרויקט Node.JS שלכם, ואחר כך נראה את שיטת העבודה עם קומפוננטות ואיך היא עוזרת לנו לכתוב קוד נקי ובקלות.

זה הקישור להרשמה: https://www.tocode.co.il/workshops/109

ביום חמישי שאחריו (ה 14.10) אעביר שעה על React Testing Library. המפגש הזה יתמקד בטיפים ודוגמאות לאנשים שכבר מכירים טוב ריאקט וכותבים בדיקות ב react-testing-library או ספריה אחרת. אז אם התחלתם לכתוב בדיקות UI ונתקעתם או שהיו לכם שאלות או שפשוט רוצים לראות עוד גישה לכתיבת הבדיקות הוובינר הזה בשבילכם.

זה הקישור להרשמה: https://www.tocode.co.il/workshops/108

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

זה הקישור להרשמה: https://www.tocode.co.il/workshops/107

וביום חמישי האחרון של החודש (ה 28.10) ניקח צעד אחורה מעולם הווב ונלך לראות מה חדש ב Python 3.10, כשהפיצ'ר שייקח לנו את עיקר הזמן בוובינר יהיה ה Pattern Matching ואני אשתדל להספיק לדבר על עוד 2-3 פיצ'רים קטנים יותר.

זה הקישור להרשמה: https://www.tocode.co.il/workshops/110

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

היום למדתי: סדר המפתחות ב 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 קובע את צבע הטקסט לגוון מסוים של ירוק. אתם מוזמנים לנסות לנחש מה אומר כל אחד מהקלאסים האחרים.

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

המשך קריאה