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

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

על שליחת פרמטרים בלי Content Type (ולמה התקלקל לי הדמו בוובינר אתמול)

04/02/2022

במהלך וובינר על Next.JS שהעברתי אתמול ניסיתי לשלוח הודעה לשרת מתוך curl עם הפקודה הבאה:

$ curl -X POST -d hello 'localhost:3000/api/todos'

קוד צד השרת שקיבל את ההודעה נראה כך:

export default function handler(req, res) {
  console.log(`add ${JSON.stringify(req.body)}`);
  addTodo(req.query.text);
  console.log(`todos = ${JSON.stringify(getTodos())}`);
  res.status(200).json({});
}

וכמו שקורה לעתים קרובות כשמנסים לאלתר במהלך Live Coding הקוד לא עבד. במקום ש req.body יכיל את המילה hello כמו שהתכוונתי שיקרה, הוא הכיל אוביקט. תוצאת ההדפסה היתה:

add {"hello":""}

כלומר req.body הכיל אוביקט עם מפתח יחיד בשם hello וערך ריק.

מה?

בחזרה ל curl, המתג -d אומר שמה שיבוא אחריו הוא גוף ההודעה, והמתג -X POST אומר שאני שולח בקשה מסוג POST. בסך הכל יש לנו בקשת POST שגוף ההודעה שלה מורכב מהמילה הבודדת hello. אז איך req.body הגיע להיות אוביקט, ואיך hello הגיע להיות המפתח?

המשך קריאה

יאמל הוא לא חבר

02/02/2022

הפופולריות של דוקר וקוברנטיס הביאה לתודעה הציבורית גם את פורמט קבצי ההגדרות yaml, שזה קיצור ל Yaml Ain't Markup Language (בגירסה המקורית זה היה yet another markup language).

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

הנה דוגמה אחת לבור כזה שפגשתי לאחרונה - הקוד הבא ב docker-compose.yml מפעיל ubuntu שידפיס את הטקסט yes we can:

version: "3.9"

services:
  app:
    image: ubuntu
    command: bash -c "echo $$text"
    environment:
      text: yes we can

אבל אם נשנה את הטקסט ונישאר רק עם המילה yes:

version: "3.9"

services:
  app:
    image: ubuntu
    command: bash -c "echo $$text"
    environment:
      text: yes

אז הפלט משתנה בהתאמה והופך למילה הבודדת true.

הסיבה לשינוי היא שלמרות שאין חובה להשתמש במרכאות סביב מחרוזות ביאמל, בכתיבה בלי מרכאות הקוד שמפענח את היאמל צריך להבין לבד מה טיפוס הנתונים של הערך. במפתח image הערך ubuntu יהיה מחרוזת, וגם הערך של משתנה הסביבה היה מחרוזת כשהוא החזיק את הטקסט yes we can. אבל, המילה yes מפוענחת בתור ערך בוליאני ולכן מומרת לערך הבוליאני true.

הסקרנים שביניכם יכולים למצוא את מסמך הכללים המלא של יאמל בקישור: https://yaml.org/spec/1.2.2/, אבל אני לא בטוח שהקריאה בו תעשה לכם חשק לכתוב יותר יאמלים.

פישינג פישינג פישינג

01/02/2022

המייל הזה הגיע היום-

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

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

ואז היה לינק לתשלום עבור החבילה שלי.

בואו נדבר עליו.

המשך קריאה

הזמנה לוובינר: Next.JS

31/01/2022

אחת השאלות הכי נפוצות כשאנשים מתחילים לעבוד עם React ו Node היא איך לחבר את שני הדברים יחד ולהעלות לאוויר אפליקציה מלאה.

מצד אחד הגישה "הפשוטה" לחיבור ריאקט לקוד צד שרת עובדת גם בעבודה מול Node: אנחנו בונים API באקספרס שיודע לטפל ב CORS, מתוך ריאקט שולחים בקשות Ajax ל API הזה ומציגים את התשובות. אפליקציית ריאקט מוגשת בצורה עצמאית מתוך nginx, שמשמש גם בתור Reverse Proxy ל Express.

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

  1. אין תמיכה ב Server Side Rendering.

  2. אין דרך קלה לשתף קוד בין אפליקציית הריאקט לאפליקציית ה Node.JS.

  3. צריך לבנות לבד מנגנוני Build לשתי הסביבות.

  4. צריך להתארגן על שרת ו nginx, ולתחזק אותו.

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

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

  1. איך לבנות יישום Next.JS מאפס.

  2. איך להריץ אותו במצב פיתוח.

  3. איך Next.JS מחברת בין קוד ריאקט לקוד Node.JS, איך בונים API Endpoints ואיך מפעילים Server Side Rendering.

  4. איך להעלות את היישום שכתבנו לענן כך שיהיה זמין מכל מקום.

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

לפרטים והצטרפות מוזמנים להיכנס לדף הוובינר בקישור: https://www.tocode.co.il/workshops/111

מה האורך של דגל ישראל ב 2022

30/01/2022

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

המשך קריאה

קריאה מודרכת בקוד של Axios

29/01/2022

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

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

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

המשך קריאה

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

28/01/2022

אם כתבת קומפוננטת ריאקט וקובץ בדיקות עבורה, ועדיין יש באגים, זה אומר ש-

  1. לא כתבת בדיקות מספיק טובות?

  2. לא כתבת מספיק בדיקות?

  3. יש באגים שבדיקות לא יכולות לאתר?

  4. כתיבת בדיקות לא שווה את הזמן שלך?

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

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

היום למדתי: משתנים גלובאליים ב node.js

27/01/2022

פיצ'ר שאף פעם לא חשבתי שאצטרך ב Node.JS הוא המשתנה המיוחד global. כמו window בדפדפן, global הוא האוביקט ש node הולך אליו כשפניתם למשתנה אבל node לא מצליח למצוא את המשתנה הזה בשום מקום. על global אנחנו נוכל למצוא את הדברים הגלובאליים של נוד כמו setTimeout, clearTimeout וכמובן גם את global עצמו.

בעזרת global אנחנו יכולים לשתול משתנה גלובאלי בקובץ אחר. לדוגמה נניח שיש לי קובץ בשם b.js עם התוכן הבא:

console.log(foo);

אז ברור שאם ננסה להריץ ישירות את b.js נקבל שגיאה כי foo אינו משתנה מוגדר. אבל במקום להריץ את b.js אני יכול לכתוב קובץ חדש בשם a.js לדוגמה עם התוכן הבא:

global.foo = 10;
const b = require('./b.js');

ועכשיו כשאני מריץ את a.js הוא יטען את b.js ו b כבר ימצא את המשתנה foo כי הוא הוגדר על global בקובץ a.

נ.ב. מתי נרצה להשתמש ב global אתם שואלים? בגדול אף פעם. בקטן דמיינו שאתם צריכים להריץ בדיקות עם react-testing-library בתוך סביבת node.js, למשל ב jest או mocha. דמיינו גם שהיישום שלכם טוען איזה קובץ שמותאם לריצה בדפדפן כי הוא משתמש באיזשהו אוביקט גלובאלי כמו window, fetch או IntersectionObserver (כן יש דבר כזה). עכשיו בשביל להריץ את הבדיקה על היישום שלכם אתם צריכים שאותו קובץ יצליח למצוא את ה window או ה fetch הגלובאליים.

הספריה node-window-polyfill מספקת דוגמה לשימוש כזה ב global כדי לייצר משתנה window שכולם יכירו. הנה סניפט ממנה שממחיש את הנקודה:

var globalObject = global;

var registerWindow = function () {
    globalObject.window = globalObject.window || {};
    exports.registerWindowProperties();
};

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