שלום אורח התחבר

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

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

מעדיפים לקרוא מהטלגרם? בקרו אותנו ב:@tocodeil

או הזינו את כתובת המייל וקבלו את הפוסט היומי בכל בוקר אליכם לתיבה:

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

Warning: Invalid DOM property `class`. Did you mean `className`?

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

import "./styles.css";

export default function App() {
  return (
    <div class="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

ל div המרכזי יהיה את הקלאס App.

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

export default function App(props) {
    const { class } = props;
}

שלא היה עובד בגלל ש class זו מילה שמורה.

וכן ברור שהיינו יכולים לכתוב במקום משהו כזה:

export default function App(props) {
    const { class: className } = props;
    // now I use className inside the component, to handle the "class" from outside
}

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

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

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

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

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

  1. לכתוב אתר בסיסי עם מערכת ניהול

  2. לכתוב רשת חברתית

  3. לכתוב אתר כמו ויקס - שכל אחד יכול ליצור תוכן לעצמו

  4. לכתוב מערכת של חנות דיגיטלית

  5. לכתוב API ולתקשר איתו מתוך אפליקציית Front End

  6. לכתוב Rails Engine המשותף למספר פרויקטים

  7. לכתוב ולהפיץ Rails Gem

  8. לשכתב את ה Rails Gem שלך כשיש לך הרבה משתמשים ואתה מגלה שה API כבר לא מספיק טוב

  9. לכתוב מערכת Real Time Web בה גולשים משתפים תוכן ורואים תוכן של אחרים בזמן אמת

  10. לתקן בעיות אבטחה בשרת ריילס שנפרץ

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

  12. לתקן בעיות ביצועים ו Deadlocks במערכת גדולה עקב עומס משתמשים

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

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

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

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

המשך קריאה...

זה מרגיש כאילו רק אתמול פרסמתי כאן מדריך איך לעבוד עם React ב Rails 6 והנה יצאה ריילס 7 עם גישה חדשה לגמרי לעבודה עם JavaScript. בפוסט זה נראה את הג'ם vite-ruby שמאפשר לנו לבנות אפליקציית ריאקט עם ריילס 7 גם בלי webpacker.

השינוי הגדול המרכזי של Rails 7 ביחס לעבודה עם JavaScript הוא ההחלטה לוותר על שלב ה Precompilation. הטענה של DHH היא שהטכנולוגיות בשלות: עם HTTP Push אפשר להחליף את ה Bundling בלי לאבד ביצועים, ודפדפנים יודעים כבר להריץ JavaScript ברמה טובה כך שלא צריך Babel. נכון, אנחנו מפסידים את scss אבל אולי זה לא סוף העולם.

הקורבן הגדול ביותר של ההחלטה הזאת הוא דווקא JSX, כי בלי pre-compilation אין מי שיהפוך את ה JSX-ים לקוד JavaScript רגיל. לפני כמה ימים כתבתי על ספריית htm והיא יום אחד תהיה המפתח לחיבור. הבעיה שכרגע העבודה עם jspm ובאופן כללי עם import maps לא מספיק יציבה - הרבה מודולים ב jspm ייכשלו אם ננסה להוריד אותם אלינו, ואחרים ייכשלו בכל מקרה. כן אפשר לתקן כל תקלה, אבל אם אתם רוצים שהכלים יעבדו בשבילכם ולא אתם בשביל הכלים אני ממליץ בינתיים לחכות עם import maps.

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

  1. נבנה אפליקציית ריילס ואפליקציית ריאקט שמחוברת אליה באמצעות הג'ם vite-rails.

  2. נעביר משתנים מריילס לריאקט באמצעות הג'ם gon.

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

מוכנים? בואו נצא לדרך.

המשך קריאה...

בתיקיה חדשה ניצור 3 קבצים. הראשון הוא Dockerfile:

FROM ubuntu:22.04

WORKDIR /app

COPY . .

RUN chmod +x /app/startup.sh

CMD ["/app/startup.sh"]

השני נקרא startup.sh ומכיל את התוכן הבא:

#!/bin/bash

echo Hello World

והשלישי docker-compose.yml עם התוכן הבא:

version: "3.9"

services:
  app:
    build: .
    volumes:
      - .:/app

אני מפעיל:

$ docker compose build
$ docker compose run

ומקבל את השגיאה:

[+] Running 1/1
 ⠿ Container chmod-in-run-app-1  Recreated                                                                         0.2s
Attaching to chmod-in-run-app-1
Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/app/startup.sh": permission denied: unknown

מה קרה שם? איך נתקן?

המשך קריאה...

לא רואה את זה

לא רואה את זה

לא רואה את זה

לא רואה את זה

לא רואה את זה

רואה את זה

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

מהר מאוד הם מגלים שידע לא מדבק.

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

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

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

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

במילים אחרות - מה החסרונות של טייפסקריפט בפרויקט הספציפי שלכם?

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

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

נ.ב. הסקירה הזאת על ראסט: https://www.bunniestudios.com/blog/?p=6375 היא דוגמה מעולה לסקירה טכנולוגית שמציגה גם את העלויות ולא רק יתרונות מובהקים או חסרונות מובהקים.

את AMD הכרתי באמצעות require.js שהיתה להיט באזור שנת 2012 (מה שנקרא, עובד ב IE6) וכנראה גם קצת קודם. מה ש require עשתה היה לאפשר לכם לכתוב בתוך קובץ JavaScript אחד פקודה שתטען קובץ JavaScript אחר. נכון, לפני require היתה את dojo שעבדה על אותו מנגנון אבל זה כבר למתקדמים.

ל Require היה כלי אופטימיזציה שלוקח קבצים שכתובים ב AMD ומאחד אותם יחד לקובץ אחד וככה מצליח לשפר את זמן טעינת העמוד, כי צריך לשלוח פחות קבצים לדפדפן. אחרי זה הגיעו grunt, gulp, webpack ו babel ואנחנו עברנו להשתמש בכתיב ה import/export ולהריץ קוד על קבצי ה JavaScript בתוך שלב האופטימיזציה.

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

נגלגל קדימה ל 2022 והעולם השתנה שוב. היום דפדפנים תומכים תמיכה מלאה ב ES Modules ובטעינת קובץ JavaScript מתוך קובץ אחר. בנוסף תקן HTTP/2 תומך ב Server Push שאומר שאין ייתרון מבחינת ביצועים ל Bundling.

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

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

המשך קריאה...

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

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

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

המשך קריאה...

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

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

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

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

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

$ git branch --unset-upstream

ועכשיו ניסיון לעשות push ייכשל עם ההודעה:

fatal: The current branch mybranch has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin mybranch

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

$ git push origin mybranch

והיתרון הוא שכבר אי אפשר לכתוב בטעות git push מיד אחרי קומיט ואחרי זה לאכול את הלב כשצריך לתקן שגיאת כתיב.