ToCode @tocodeil Channel on Telegram

ToCode

@tocodeil


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

ToCode (Hebrew)

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

ToCode

21 Nov, 05:15


מציפיות לתוכנית עבודה
יש שתי בעיות עם ציפיות גבוהות מדי:

1. כשזה לא מצליח אנחנו נוטים להתאכזב ולהתייאש.

2. ככל שאנחנו פחות מבינים בתחום ככה הציפיות שלנו יהיו עוד יותר לא ריאליות.

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

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

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

ToCode

21 Nov, 05:15


https://www.tocode.co.il/blog/2024-11-dreams-come-true

ToCode

20 Nov, 05:15


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

https://matanbobi.dev/posts/stop-passing-setter-functions-to-components

הקוד שהוא הדביק נראה ככה:

// Form.jsx 
function Form() {
const [formData, setFormData] = useState({ name: '' });
return (
<div>
<h1>Form</h1>
{/* Pass the setter function down to ChildComponent */}
<Input name={formData.name} setFormData={setFormData} />
<button onClick={() => console.log(formData)}>Submit</button>
</div>
);
};

// Input.jsx
function Input({ name, setFormData }) {
const handleInputChange = (event) => {
// Directly using the setFormData setter function from the parent
setFormData((prevData) => ({ ...prevData, name: event.target.value }));
};

return (
<div>
<label>
Name:
<input type="text" value={name} onChange={handleInputChange} />
</label>
</div>
);
};


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

setFormData((prevData) => ({ ...prevData, name: event.target.value })); 


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

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

// Form.jsx 
function Form() {
const [name, setName] = useState('');
const [favoriteColor, setFavoriteColor] = useState('#000000);

return (
<div>
<h1>Form</h1>
<Input label="Name" value={name} setter={setName} />
<Input label="Favorite Color" value={favoriteColor} setter={setFavoriteColor} />
</div>
);
};

// Input.jsx
function Input({ label, value, setter }) {
const handleInputChange = (event) => {
setter(event.target.value);
};

return (
<div>
<label>
{label}:
<input type="text" value={value} onChange={handleInputChange} />
</label>
</div>
);
};


במצב כזה עדיין העברתי את ה setters פנימה לקומפוננטת ה Input אבל אם יהיה שינוי באיך ש Form שומר את המידע לא תהיה בעיה לשנות את הקוד רק בקומפוננטת Form - למשל ליצור פונקציה חדשה שמקבלת את הערך החדש ולהעביר אותה פנימה ל Input. כלומר מה שהיה חשוב בדינמיקה בין שתי הקומפוננטות הוא הממשק ביניהן.

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

ToCode

20 Nov, 05:15


https://www.tocode.co.il/blog/2024-11-react-passing-setters-down

ToCode

19 Nov, 05:15


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

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

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

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

ToCode

19 Nov, 05:15


https://www.tocode.co.il/blog/2024-11-i-vs-we

ToCode

18 Nov, 05:16


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

אנחנו אוהבים את זה כי הלוטו מסתדר רעיונות שיש לנו כבר בראש:

1. "אם לא תנסה איך תזכה"

2. "זה רק 20 ש"ח, חבל לא לנסות"

3. "ממילא אין לי משהו אחר לעשות עם הכסף"

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

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

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

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

ToCode

18 Nov, 05:16


https://www.tocode.co.il/blog/2024-11-cost-of-a-lottery-ticket

ToCode

17 Nov, 05:15


סקאלת הישגיות - סקרנות
- הולך ל Chat GPT ומבקש פיתרון.

- הולך ל Chat GPT ומבקש 3 פיתרונות, עם יתרונות וחסרונות של כל אחד כדי שאוכל לבחור את הטוב ביותר.

- הולך ל Chat GPT ומבקש כיוון כללי לפיתרון. את השאר אמצא בגוגל ובתיעוד.

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

- כותב לבד POC, מחפש לשבור אותו ורק כשהכל עובד ואני מבין כל פסיק מוחק את ה POC וכותב את הקוד האמיתי.

- כותב לבד קוד אמיתי אחרי מחקר וכתיבת POC, ואז מוסיף בדיקות ותיעוד.

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

ToCode

17 Nov, 05:15


https://www.tocode.co.il/blog/2024-11-curiosity

ToCode

16 Nov, 05:15


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

והדבר אפילו יותר נכון כשמדובר בקוד.

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

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

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

ToCode

16 Nov, 05:15


https://www.tocode.co.il/blog/2024-11-too-easy

ToCode

15 Nov, 05:15


if (value > maxValue.value) {        
maxIndex.value = counterIndex;
maxValue.value = value;
}
}
</script>

<template>
<Counter @change="(newValue) => onNewValue(0, newValue)" :isMax="maxIndex == 0" />
<Counter @change="(newValue) => onNewValue(1, newValue)" :isMax="maxIndex == 1" />
<Counter @change="(newValue) => onNewValue(2, newValue)" :isMax="maxIndex == 2" />
<Counter @change="(newValue) => onNewValue(3, newValue)" :isMax="maxIndex == 3" />
</template>


ואת קומפוננטת המונה באופן הבא:

<script setup lang="ts">
import { ref, computed } from 'vue'

const count = ref(0)
const emit = defineEmits(['change']);
const {isMax} = defineProps<{isMax?: boolean}>();
const background = computed(() => isMax ? "green" : "yellow");

function onClick() {
count.value++;
emit('change', count.value);
}
</script>

<template>
<div>
<p>Value = {{ count }}</p>
<button @click="onClick">+1</button>
</div>
</template>

<style scoped>
div {
background-color: v-bind(background);
padding: 20px;
}

button {
color: white;
}

p {
color: black;
}
</style>


יתרונות וחסרונות בשתי הגישות
נשים לב להבדלים וליתרונות והחסרונות בין שתי הגישות:

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

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

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

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

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

עכשיו אתם
1. עדכנו את שני הפיתרונות כך שישתמשו ב v-for במקום לשכפל את יצירת המונה 4 פעמים.

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

ToCode

15 Nov, 05:15


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

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

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

הקוד לקומפוננטה העוטפת הוא בסך הכל:

<script setup lang="ts">
import {ref, computed} from 'vue';
import Counter from './Counter.vue';

const counts = ref([0, 0, 0, 0]);
const maxValue = computed(() => Math.max(...counts.value));
const maxIndex = computed(() => counts.value.findIndex(el => el === maxValue.value));

function onClick(counterIndex) {
counts.value[counterIndex]++;
}
</script>

<template>
<p>max value = {{ maxValue }}</p>
<p>max index = {{ maxIndex }}</p>
<Counter @click="onClick(0)" :isMax="maxIndex == 0" :count="counts[0]"/>
<Counter @click="onClick(1)" :isMax="maxIndex == 1" :count="counts[1]"/>
<Counter @click="onClick(2)" :isMax="maxIndex == 2" :count="counts[2]"/>
<Counter @click="onClick(3)" :isMax="maxIndex == 3" :count="counts[3]"/>
</template>


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

<script setup lang="ts">
import { ref, computed } from 'vue'

const emit = defineEmits(['click']);
const {isMax, count} = defineProps<{isMax?: boolean, count: number}>();
const background = computed(() => isMax ? "green" : "yellow");

function onClick() {
emit('click');
}
</script>

<template>
<div>
<p>Value = {{ count }}</p>
<button @click="onClick">+1</button>
</div>
</template>

<style scoped>
div {
background-color: v-bind(background);
padding: 20px;
}

button {
color: white;
}

p {
color: black;
}
</style>


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

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

emit('change', 10);


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

<Counter @change="(newValue) => doSomethingWith(newValue)" />


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

<script setup lang="ts">
import {ref} from 'vue';
import Counter from './Counter.vue';

const maxValue = ref<null|number>(null);
const maxIndex = ref<null|number>(null);

function onNewValue(counterIndex, value) {

ToCode

15 Nov, 05:15


https://www.tocode.co.il/blog/2024-11-vue-example-counters

ToCode

14 Nov, 05:15


ארבעה דברים שממש אהבתי ב Nuxt
נוקסט היא גירסת ה Full Stack של Vue המאפשרת פיתוח יישומים מלאים עם Server Side Rendering. אני חייב להודות שכשהתחלתי לשחק עם הפריימוורק הייתי בטוח שאני הולך לפגוש עוד next.js ושמחתי למצוא מספר פיצ'רים ייחודיים שמיד עשו חשק ללמוד יותר. אלה הדברים שכבר ממבט ראשון על nuxt אהבתי במיוחד:

1. יבוא אוטומטי - כן אני יודע VS Code משלים פקודות import בלי מאמץ ובכל זאת אין קוד תמיד עדיף על קוד שנכתב מהר. קטע כזה עובד ב nuxt בלי שנצטרך להוסיף שום פקודת import:

<script setup lang="ts">
/* ref() and computed() are auto-imported */
const count = ref(1)
const double = computed(() => count.value * 2)
</script>


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

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

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

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

ToCode

14 Nov, 05:15


https://www.tocode.co.il/blog/2024-11-nuxt

ToCode

13 Nov, 05:15


https://www.tocode.co.il/blog/2024-11-python-project-suggestions

ToCode

12 Nov, 06:26


זהירות פלסטר
המתכון הוא פשוט-

1. כותבים קוד תשתית.

2. צריכים פיצ'ר או תיקון באג והקוד לא מסתדר עם התשתית.

3. מתקנים את התשתית.

4. בונים את הפיצ'ר עם התשתית החדשה.

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

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

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

ToCode

12 Nov, 06:26


https://www.tocode.co.il/blog/2024-11-just-a-patch-fixed