en
Feedback
ToCode

ToCode

Open in Telegram

טיפים ×§×¦×Ø×™× ×œ×ž×Ŗ×›× ×Ŗ×™× ×ž××Ŗ ינון פרק

Show more
1 419
Subscribers
No data24 hours
No data7 days
+130 days
Posts Archive
ToCode
1 419
# שלושה נכהים ×©××Ŗ× יכולים ×œ×‘× ×•×Ŗ לבד וכמעט בחינם ×œ×ž×Ø×•×Ŗ שאני לא אוהב את ההגנון, אי אפשר ×œ×”×Ŗ×•×•×›×— עם ×”×¤×Ŗ×’× הישן ×©××•×ž×Ø שעדיף ללמד בן אדם לדוג ×ž××©×Ø לתת לו דג. ×”×ž×™×•×ž× ×•×Ŗ להשיג אוכל ×ž××¤×©×Ø×Ŗ לבן אדם להמשיך ×œ×”×©×Ŗ×ž×© בה ככל שירצה. באותו אופן אנחנו חושבים על ההבדל בין נכהים לבין ×›×”×£. ×”×›×”×£ ממלא ×¦×•×Ø×š מיידי והנכה יכול ×œ×¢×–×•×Ø לנו ×œ×”×Ø×•×•×™×— עוד ועוד ×›×”×£ ×œ××•×Ø×š זמן. חלק מהנכהים של העולם ×”×ž×•×“×Ø× ×™ הם קשים להשגה ×•×™×§×Ø×™×: נדל"ן, תואר אקדמי או ×ž×•×Ŗ×’ חזק, כולם יביאו ערך ×ž×©×ž×¢×•×Ŗ×™ לבעלים שלהם וכל אחד מהם דורש השקעה ×ž×©×ž×¢×•×Ŗ×™×Ŗ בכהף ובזמן לפני ×©×ž×Ŗ×—×™×œ×™× ×œ×Ø××•×Ŗ תוצאות. אבל ×”××™× ×˜×Ø× ×˜ והכלכלה ×”×ž×•×“×Ø× ×™×Ŗ ×™×•×¦×Ø×™× גם הוג חדש של נכהים, נכהים ×©×“×•×Ø×©×™× מעט מאוד השקעה כהפית ושכל אחד יכול ×œ×‘× ×•×Ŗ ×œ×’×ž×Ø×™ לבד ×ž×”×‘×™×Ŗ. הנה שלוש ×“×•×’×ž××•×Ŗ לנכהים כאלה שאולי לא יהפכו ××Ŗ×›× ×œ×¢×©×™×Ø×™× אבל בהחלט יעזרו ×œ×™×™×¦×Ø חיים יותר נוחים: ## ×§×©×Ø×™× אחד הביטויים היפים ×©×©×ž×¢×Ŗ×™ בהקשר הזה הוא Connection Economy שבא ×œ×”×”×‘×™×Ø ×©×§×©×Ø×™× עם אנשים ××—×Ø×™× הפכו לנכה כלכלי לכל דבר. בעולם ×”××™× ×˜×Ø× ×˜ אנחנו יכולים ×œ×™×¦×•×Ø ×§×©×Ø×™× מקצועיים בעלי ×ž×©×ž×¢×•×Ŗ עם ×›×ž×•×Ŗ עצומה של אנשים, והרבה פעמים אפילו בלי לפגוש ××•×Ŗ× פנים אל פנים. פה בארׄ המצב אפילו יותר מוצלח כי ×”×ž×Ø×—×§×™× קטנים ויש הרבה ×§×”×™×œ×•×Ŗ חזקות ×©×ž×™×™×¦×Ø×•×Ŗ מפגשים פיזיים ×œ×—×‘×Ø×™×. רוב האנשים הביבכם מוקפים כל היום באינהוף ×¤×™×Ø×”×•×ž×•×Ŗ וכבר נהיינו אטומים לרעש שלהן. ×œ×¢×•×ž×Ŗ זאת רובנו שמחים לקבל המלצה ×ž×—×‘×Ø על ×ž×•×¦×Ø שהוא אהב או על בעל מקצוע שעזר לו. הפציפית בעולם הפיתוח, בניית ×¤×Ø×•×™×§×˜-צד עם עוד אנשים, מפגש בכנה והעברת הרצאה, או אפילו עזרה בקבוצת פייהבוק יכולים ×œ×¢×–×•×Ø לאנשים ×œ×”×›×™×Ø ××Ŗ×›× ×ž×§×¦×•×¢×™×Ŗ. בעתיד כשהם ×™×¦×˜×Ø×›×• בעל מקצוע או יחפשו לגייה עובד ××Ŗ× תקפצו בראש ×”×Ø×©×™×ž×”. ×”×“×Ø×š הכי טובה ×œ×¤×Ŗ×— ×§×©×Ø×™× היא פשוט ×œ×¢×–×•×Ø ×ž×§×¦×•×¢×™×Ŗ לאנשים בכל ×”×–×“×ž× ×•×Ŗ שיש לכם, ×•×œ×™×™×¦×Ø עוד ועוד ×”×–×“×ž× ×•×™×•×Ŗ כאלה - אם זה ×œ×œ×›×Ŗ לכנהים, ×œ×”×¦×˜×Ø×£ ×œ×¤×™×Ŗ×•×— של ×¤×Ø×•×™×§×˜ קוד פתוח שקרוב ללבכם, להקים ×ž×¢×Ø×›×Ŗ בהתנדבות שתפתור בעיה ×œ××Ø×’×•×Ÿ שקרוב ללבכם, ×œ×¢×–×•×Ø בקבוצות פייהבוק ×•×˜×œ×’×Ø×, בקיצור לחפש ×“×Ø×›×™× לעבודה ×ž×§×¦×•×¢×™×Ŗ עם מעגלים שונים ×•×Ø×—×‘×™× של אנשים. ## ×ž×™×•×ž× ×•×Ŗ ×˜×›× ×™×Ŗ עולם העבודה הופך נישתי ומקצועי יותר ויותר כל שנה והדרישה ×œ×ž×¤×Ŗ×—×™× מקצועיים רק גדלה. באותו זמן אין מהפיק אנשים שמוכנים להשקיע מהפיק בפיתוח ×”×ž×™×•×ž× ×•×Ŗ ×”×ž×§×¦×•×¢×™×Ŗ שלהם. כך נוצר מצב שמצד אחד יש המון ג'×•× ×™×•×Ø×™× שמחפשים עבודה בהייטק ומצד שני יש המון ×ž×©×Ø×•×Ŗ פנויות שחברות לא ×ž×¦×œ×™×—×•×Ŗ לאייש כי "אין אנשים טובים". אפשר לדמיין את עובדי ההייטק הפוטנציאלים ×ž×”×•×“×Ø×™× ×›×¤×™×Ø×ž×™×“×” כאשר בתחתית ×”×¤×™×Ø×ž×™×“×” אנחנו מוצאים ג'×•× ×™×•×Ø×™× ואנשים ללא ניהיון וככל שעולים ×‘×Ø×ž×Ŗ ×”×ž×™×•×ž× ×•×Ŗ יש פחות אנשים ×ž×Ŗ××™×ž×™×. השקעה ×‘×ž×™×•×ž× ×•×Ŗ ×‘××ž×¦×¢×•×Ŗ לימוד קורה, ביצוע ×¤×Ø×•×™×§×˜-צד בטכנולוגיה חדשה, השתתפות ×‘×¤×Ø×•×™×§×˜ קוד-פתוח ×ž×Ø×›×–×™ בעולם ×”×Ŗ×•×›×Ÿ שלכם, ×”×Ŗ×ž×§×“×•×Ŗ בעולם ×Ŗ×•×›×Ÿ הפציפי והיכרות עם כל מה שקורה בו או בכל ×“×Ø×š אחרת תעזור לכם ×œ×¢×œ×•×Ŗ שלבים ×‘×¤×™×Ø×ž×™×“×”. ×ž×™×•×ž× ×•×Ŗ ×˜×›× ×™×Ŗ היא × ×›×”, כי היא תאפשר לכם ×Ŗ×ž×™×“ למצוא עבודה ×‘×Ŗ× ××™× ×©×ž×Ŗ××™×ž×™× לכם. ## בניית ×¤×Ø×•×™×§×˜ SaaS ×ž×”×‘×™×Ŗ × ×›×” שלישי ×©××Ŗ× יכולים ×œ×‘× ×•×Ŗ ×œ×’×ž×Ø×™ לבד (אבל ×œ×“×¢×Ŗ×™ הוא הקשה ביותר) הוא ×ž×¢×Ø×›×Ŗ תוכנה שאנשים ××—×Ø×™× יהיו מוכנים לשלם עליה. ××Ŗ× לא ×¦×Ø×™×›×™× ×œ×”×Ŗ×—×Ø×•×Ŗ בגוגל או בפייהבוק, מהפיק ×œ×‘×—×•×Ø נישה שאף חברת הטארט-אפ או ×¢× ×§×™×Ŗ טכנולוגיה לא ×ž×Ŗ×¢× ×™×™× ×Ŗ בה, ×œ×¤×Ŗ×•×Ø לאנשים בעיה הפציפית ולהציע ×ž×—×™×Ø ××˜×Ø×§×˜×™×‘×™. ההפר Start Small Stay Small מציע מהלול חשיבה מאוד טכני ×œ×¤×™×Ŗ×•×— ×¤×Ø×•×™×§×˜ Saas עבור ×ž×Ŗ×›× ×Ŗ×™× ×©×Ø×•×¦×™× להצליח בכוחות עצמם ואני מאוד ממליׄ ×œ×§×Ø×•× אותו אם זה משהו ×©×ž×“×‘×Ø אליכם. באתר Indie Hackers אפשר למצוא אינהוף ×”×™×¤×•×Ø×™× על ×¤×Ø×•×™×§×˜×™× קטנים שלא מעט מהם ×ž××¤×©×Ø×™× ×œ×ž×¤×Ŗ×—×™× שלהם ×œ×—×™×•×Ŗ בכבוד רק ×ž×”×”×›× ×”×•×Ŗ ×ž××•×Ŗ×• ×¤×Ø×•×™×§×˜. × ×›×” תוכנה שווה היום לא פחות מכל חנות פיזית, אבל הבניה שלו כמעט לא דורשת השקעה כהפית וגם אנשים עובדים יכולים להשקיע בנכה כזה בשעות הפנאי. יש לכם רעיונות לנכהים נוהפים שאנחנו יכולים ×œ×¤×Ŗ×— לבד ×ž×”×‘×™×Ŗ? מוזמנים בחום לשתף בתגובות.

ToCode
1 419
    const newTreeData = await loadChildren(treeData, key, children);
    setTreeData(newTreeData);
  };


  return (
    <Tree loadData={onLoadData} treeData={treeData} />
  );
}
## איפה ללמוד עוד לעׄ של antd יש עוד המון ×™×›×•×œ×•×Ŗ ואפשר ×œ×§×Ø×•× עליהן עם ×“×•×’×ž××•×Ŗ בדף התיעוד של העׄ כאן: https://ant.design/components/tree/ והחלק היותר מעניין בדף הוא ×Ø×©×™×ž×Ŗ ×”×§×•×ž×¤×•× × ×˜×•×Ŗ בצד שמאל. פשוט ×Ŗ×œ×—×¦×• על כל קומפוננטה ×ž×”×Ø×©×™×ž×” כדי ×œ×Ø××•×Ŗ מה היא עושה ואיך ×œ×”×©×Ŗ×ž×© בה.

ToCode
1 419
# משחקים עם Antd - ×§×•×ž×¤×•× × ×˜×Ŗ עׄ אהינכרונית הפריית antd היא אחת ×ž×”×¤×Ø×™×•×Ŗ ה UI ×”×¤×•×¤×•×œ×Ø×™×•×Ŗ ×‘×Ø×™××§×˜ ואני ×œ×’×ž×Ø×™ מבין למה. ה API מאוד פשוט, יש הרבה ×§×•×ž×¤×•× × ×˜×•×Ŗ שנראות טוב ואפשר ×œ×”×Ø×—×™×‘ אותה ×™×—×”×™×Ŗ ×‘×§×œ×•×Ŗ. הנה דוגמה לקומפוננטה של העׄ שלהם ולשימוש אהינכרוני בו כדי לייצג מידע שנטען ×ž×©×Ø×Ŗ. ## מה אנחנו בונים הדוגמה של היום ×Ŗ×©×Ŗ×ž×© ×‘×§×•×ž×¤×•× × ×˜×Ŗ Tree של antd כדי ×œ×”×Ø××•×Ŗ עׄ שמציג את כל ×”×”×Ø×˜×™× של ×ž×œ×—×ž×Ŗ הכוכבים, וכשלוחצים על הרט הוא יטען את ×©×ž×•×Ŗ כל ×”×“×ž×•×™×•×Ŗ באותו הרט ויציג ××•×Ŗ× בתור ילדים בעׄ. ככה זה נראה ועובד בקודהנדבוקה: <iframe src="https://codesandbox.io/embed/fervent-robinson-bse0b?fontsize=14&hidenavigation=1&module=%2Fsrc%2FApp.js&theme=light" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" title="fervent-robinson-bse0b" allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"></iframe> ## איך בנוי עׄ בשביל להציג עׄ עם ×§×•×ž×¤×•× × ×˜×Ŗ עׄ של antd אנחנו ×¦×Ø×™×›×™× מבנה × ×Ŗ×•× ×™× שמכיל ×ž×¢×Ø×š של אוביקטים, כאשר לכל אוביקט יש מאפיין key ייחודי, מאפיין title אופציונאלי שמכיל את הטקהט של האוביקט ומאפיין children אופציונאלי שמכיל את כל הילדים. אם ××Ŗ× יודעים שלא יהיו ילדים ×œ×¦×•×ž×Ŗ מהוים אפשר להוהיף מאפיין isLeaf עם ×”×¢×Ø×š true. האוביקט הבא מייצג עׄ לדוגמה:
[
    { key: 'a', title: 'A', children: [] },
    { key: 'b', title: 'B', children: [
        { key: 'bb', title: 'B-1', isLeaf: true },
        { key: 'bc', title: 'B-2', isLeaf: true },
    }}
];
בניהוי שלי רציתי ×œ×”×Ø××•×Ŗ עׄ של ×”×Ø×˜×™× כך ×©×‘×Ø×ž×” החיצונית ביותר ×Ŗ×”×™×” ×Ø×©×™×ž×” של ×”×Ø×˜×™× ולכל הרט הילדים יהיו ×”×“×ž×•×™×•×Ŗ ×©×ž×•×¤×™×¢×•×Ŗ באותו הרט. בשביל ×œ×‘× ×•×Ŗ את העׄ אני ×ž×Ŗ×—×™×œ עם ×Ø×©×™×ž×Ŗ ×”×”×Ø×˜×™× ×©× ×ž×¦××Ŗ בקישור https://swapi.py4e.com/api/films/, ואז מפעיל את הפונקציה הבאה כדי להפוך את ×”×Ø×©×™×ž×” לעׄ:
function initTree(films) {
  return films.map((film) => ({
    key: `film-${film.episode_id}`,
    title: film.title,
    children: film.characters.map((url) => ({
      key: url,
      isLeaf: true,
    })),
  }));
}
## מה קורה ×›×©×ž×©×Ŗ×ž×© לוחׄ על הרט עכשיו שיש לנו את ×”×Ø×ž×” של ×”×”×Ø×˜×™× אפשר להמשיך ×•×œ×Ø××•×Ŗ מה קורה ×›×©×ž×©×Ŗ×ž×© לוחׄ על הרט. התשובה היא שאנחנו ×¦×Ø×™×›×™× ×œ×™×¦×•×Ø את כל נתוני העׄ מחדש עם העׄ המעודכן. בעבודה עם מבני × ×Ŗ×•× ×™× ×ž×•×Ø×›×‘×™× ×©×¦×Ø×™×›×™× ×œ×”×™×©×ž×Ø בהטייט אני אוהב ×œ×”×©×Ŗ×ž×© בהפריה immer שנותנת לי ×œ×’×©×Ŗ למבנה ×”× ×Ŗ×•× ×™× כמו שהייתי כותב JavaScript ×Ø×’×™×œ והופכת את הקוד לגישה Immutable, ×›×œ×•×ž×Ø ×ž×—×–×™×Ø×” מבנה × ×Ŗ×•× ×™× חדש רק עם השינויים שביצעתי. בעזרת immer כתבתי את שתי הפונקציות הבאות ×©×œ×•×§×—×•×Ŗ עׄ ×•×ž×¤×Ŗ×— של הרט ×•×ž×ž×œ××•×Ŗ את הילדים של ×”×”×Ø×˜ בנתוני ×”×“×ž×•×™×•×Ŗ ×”××ž×™×Ŗ×™×•×Ŗ ×ž××•×Ŗ×• ×”×”×Ø×˜:

async function loadCharacter(node) {
  const res = await fetch(node.key);
  const data = await res.json();
  return { key: node.key, title: data.name, isLeaf: true };
}

async function loadChildren(treeData, filmKey, children) {
  return produce(treeData, async (draft) => {
    const node = draft.find((n) => n.key === filmKey);
    node.children = await Promise.all(children.map(loadCharacter));
  });
}
זה עובד כי ×©×ž×Ø× ×• כבר קודם ב children של כל הרט ×Ø×©×™×ž×” של ילדים ×©×”×ž×¤×Ŗ×— של כל אחד הוא בדיוק ה URL של ×”×“×ž×•×Ŗ. אני ×ž×©×Ŗ×ž×© כאן ב Promise.all ולא בלולאה כדי שכל בקשות הרשת יישלחו במקביל ולא אחת אחרי השניה. החלק ×”××—×Ø×•×Ÿ שנשאר בקוד הוא הקומפוננטה עצמה שמדביקה את כל הפונקציות שכתבנו והיא נראית כך:
import React, { useState, useEffect } from 'react';
import produce from "immer"
import { Tree } from 'antd';

import 'antd/dist/antd.css';

export default function Demo() {
  const [treeData, setTreeData] = useState(initTreeData);

  useEffect(() => {
    async function flow() {
      const res = await fetch('https://swapi.py4e.com/api/films/');
      const data = await res.json();
      setTreeData(initTree(data.results));
    };
    flow();
  }, []);

  const onLoadData = async ({ key, children }) => {

ToCode
1 419
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See /Users/ynonp/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/ynonp/.npm/_logs/2021-12-16T20_16_00_413Z-debug.log
×Ø×•××™× מה הבעיה כאן? נכון ש npm install נכשל, אבל הוא גם מציע שני פיתרונות שאת שניהם אנשים נוטים להפעיל כמעט בלי לחשוב. ×›×œ×•×ž×Ø אחרי שמישהו שרוצה ×œ×”×©×Ŗ×ž×© בהפריה שלכם רואה הודעה כזאת האינהטינקט ×”×Ø××©×•×Ÿ הוא ×œ× ×”×•×Ŗ להפעיל:
$ npm install --force
שכמובן עובד עם Warnings, ×•×ž×Ŗ×§×™×Ÿ את גירהה 16.8.1 של ×Ø×™××§×˜ בתיקיית node_modules הראשית ולא ×ž×Ŗ×§×™×Ÿ כלל את גירהה 17:
$ npm ls react

myapp@1.0.0 /Users/ynonp/tmp/mynpm/myapp
ā”œā”€ā”¬ mylib@1.0.2
│ └── react@16.8.1 deduped invalid: "^17.0.2" from node_modules/mylib
└── react@16.8.1 invalid: "^17.0.2" from node_modules/mylib

npm ERR! code ELSPROBLEMS
npm ERR! invalid: react@16.8.1 /Users/ynonp/tmp/mynpm/myapp/node_modules/react

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/ynonp/.npm/_logs/2021-12-16T20_18_56_638Z-debug.log
אז נכון אי אפשר ×œ×”×›×Ø×™×— מישהו ×œ×”×©×Ŗ×ž×© בגירהה שלך של הפריה, אבל כן יש כלים טובים כדי ×œ×’×œ×•×Ŗ אם מישהו ×”×Ŗ×§×™×Ÿ גירהה שלא ×”×ž×œ×¦×Ŗ עליה ובגלל זה הקוד לא עובד. הנה מה שחשוב ×œ×–×›×•×Ø: 1. הגדירו את ×”×“×‘×Ø×™× ×©××Ŗ× ×Ø×•×¦×™× ×©××—×Ø×™× יתקינו בתור Peer Dependencies. 2. אם קוד לקוח ×©×ž×©×Ŗ×ž×© בהפריה לא עובד, ×”×©×Ŗ×ž×©×• ב npm ls כדי לוודא ×©×”×Ŗ×œ×•×™×•×Ŗ ×©×Ø×¦×™×Ŗ× ×‘××ž×Ŗ ×ž×•×Ŗ×§× ×•×Ŗ כמו ×©×¦×Ø×™×š. 3. תקנו את ×”×Ŗ×œ×•×™×•×Ŗ ואל ×Ŗ×©×Ŗ×ž×©×• ב --force, אפילו שזה עובד.

ToCode
1 419
# היום ×œ×ž×“×Ŗ×™: אי אפשר ×œ×”×›×Ø×™×— לקוח ×œ×”×Ŗ×§×™×Ÿ הפריות Node.JS (אבל אפשר ×œ×”×Ŗ×§×Ø×‘ לזה) באג שבזבז לי יותר מדי זמן ביומיים ×”××—×Ø×•× ×™× לימד אותי לקח חשוב על npm ובעיקר על ×ž×Ŗ×›× ×Ŗ×™× אז אני כותב כאן כדי לא לשכוח ובתקווה אולי לחהוך לכם פאדיחות ×“×•×ž×•×Ŗ. ההיפור הוא פשוט - אם ××Ŗ× ×›×•×Ŗ×‘×™× ×—×‘×™×œ×Ŗ Node.JS אז ××Ŗ× יכולים לציין 3 ×Ø×©×™×ž×•×Ŗ של ×Ŗ×œ×•×™×•×Ŗ ב package.json שלכם: 1. ×Ø×©×™×ž×Ŗ dependencies ×ž×’×“×™×Ø×” ×Ø×©×™×ž×” של הפריות ×©××Ŗ× ×“×•×Ø×©×™× שהלקוח ×™×Ŗ×§×™×Ÿ הפציפית ×¢×‘×•×Ø×›× כשהוא ×ž×Ŗ×§×™×Ÿ את ההפריה שלכם. 2. ×Ø×©×™×ž×Ŗ peerDependencies ×ž×’×“×™×Ø×” ×Ø×©×™×ž×” של הפריות ×©××Ŗ× ×“×•×Ø×©×™× ש"יהיו שם" כשלקוח ×ž×Ŗ×§×™×Ÿ את ההפריה שלכם, ×›×œ×•×ž×Ø הפריות שגם ××Ŗ× ×ž×©×Ŗ×ž×©×™× בהן וגם קוד הלקוח ×ž×©×Ŗ×ž×© בהן. 3. ×Ø×©×™×ž×Ŗ devDependencies ×ž×’×“×™×Ø×” ×Ø×©×™×ž×” של ×Ŗ×œ×•×™×•×Ŗ שרק ××Ŗ× ×ž×Ŗ×§×™× ×™× במצב פיתוח. אז עכשיו בואו נבדוק מה קורה לדוגמה כשאני בונה הפריה ×©×ž×©×Ŗ×ž×©×Ŗ ×‘×Ø×™××§×˜ 17 וצריכה שהלקוח ×™×Ŗ×§×™×Ÿ את ×Ø×™××§×˜ 17 כדי לעבוד איתה. ## שימוש ב devDependencies אם אני ×ž×’×“×™×Ø את ×Ø×™××§×˜ בתור devDependency ×‘××ž×¦×¢×•×Ŗ הבלוק הבא בקובׄ package.json בהפריה שלי:
"devDependencies": {
  "react": "^17.0.2"
}
אז כשאני אעלה את ההפריה ל npm ומישהו אחר יפעיל npm install עליה, אותו מישהו אחר לא יקבל את react בכלל. ×Ø×™××§×˜ ×”×™×Ŗ×” בשימוש רק בזמן שפיתחתי את ההפריה ולא בזמן השימוש בה. ## שימוש ב dependencies אם אני ×ž×’×“×™×Ø את ×Ø×™××§×˜ בתור dependency ×‘××ž×¦×¢×•×Ŗ הבלוק הבא בקובׄ package.json בהפריה שלי:
"dependencies": {
  "react": "^17.0.2"
}
אז הלקוח ×©×ž×Ŗ×§×™×Ÿ את ההפריה שלי יקבל בתיקיית node_modules שלו את ההפריות הבאות:
node_modules
ā”œā”€ā”€ js-tokens
ā”œā”€ā”€ loose-envify
ā”œā”€ā”€ mylib
ā”œā”€ā”€ object-assign
└── react
וזה כבר נראה טוב! ×›×œ×•×ž×Ø הלקוח קיבל גם את ×Ø×™××§×˜ וגם את כל ההפריות ×©×Ø×™××§×˜ ×Ŗ×œ×•×™×” בהן. אבל כדאי לצנן את ×”×”×Ŗ×œ×”×‘×•×Ŗ. זה עובד רק בגלל שהלקוח ×Ŗ×œ×•×™ רק בהפריה שלי. אם הוא יוהיף ×Ŗ×œ×•×Ŗ בהפריה שצריכה גירהה ישנה יותר של ×Ø×™××§×˜, או אפילו ×Ŗ×œ×•×Ŗ הפציפית בגירהה ישנה יותר של ×Ø×™××§×˜ החיים הולכים ×œ×”×”×Ŗ×‘×š. נניח שקוד הלקוח שלי כולל את הבלוק הבא בקובׄ package.json שלו:
  "dependencies": {
    "mylib": "file:../mylib/mylib-1.0.1.tgz",
    "react": "16.8.1"
  }
אז עכשיו בהפעלה של npm install הוא יקבל בתיקיית node_modules את:
node_modules
ā”œā”€ā”€ js-tokens
ā”œā”€ā”€ loose-envify
ā”œā”€ā”€ mylib
ā”œā”€ā”€ object-assign
ā”œā”€ā”€ prop-types
ā”œā”€ā”€ react
ā”œā”€ā”€ react-is
└── scheduler
שזה נראה כאילו זה טוב כי הוא ×”×Ŗ×§×™×Ÿ את ×Ø×™××§×˜ אבל ×”××ž×Ŗ שהוא ×”×Ŗ×§×™×Ÿ שתי גירהאות של ×Ø×™××§×˜:
$ npm ls react
myapp@1.0.0 /Users/ynonp/tmp/mynpm/myapp
ā”œā”€ā”¬ mylib@1.0.1
│ └── react@17.0.2
└── react@16.8.1
×•×‘××ž×Ŗ ×‘×Ŗ×•×š ×Ŗ×™×§×™×™×Ŗ node_modules/mylib אני אמצא ×Ŗ×™×§×™×™×Ŗ node_modules נוהפת שבתוכה יש את ×Ø×™××§×˜ בגירהה 17.0.2, ובתיקיית node_modules הראשית אני מוצא את ×Ø×™××§×˜ בגירהה 16.8.1. לכן הגדרת dependencies לא ×‘××ž×Ŗ ×ž××¤×©×Ø×Ŗ לי "×œ×”×›×Ø×™×—" לקוח ×œ×”×Ŗ×§×™×Ÿ הפריה בגירהה ×ž×”×•×™×ž×Ŗ. אם הפריה אחרת שהוא ×Ŗ×œ×•×™ בה, או הוא עצמו, מבקשים גירהה אחרת אז זו ×Ŗ×§×‘×œ עדיפות והגירהה שאני ×Ŗ×œ×•×™ בה ×Ŗ×•×Ŗ×§×Ÿ בצורה ×¤×Ø×˜×™×Ŗ ב node_modules של ההפריה שלי. ## שימוש ב peerDependencies אופציית peerDependencies ×”×™×Ŗ×” צריכה ×œ×”×™×•×Ŗ הראשונה בניהוי כי לפי התיעוד היא עושה בדיוק את מה שאנחנו מחפשים. היא ×ž×’×“×™×Ø×” שאני ×Ŗ×œ×•×™ בהפריה אחרת אבל ×Ŗ×œ×•×Ŗ ציבורית, ×›×œ×•×ž×Ø שאני דורש שההפריה האחרת ×Ŗ×”×™×” ×‘×¤×Ø×•×™×§×˜ בגירהה שאני רוצה. ×•×‘××ž×Ŗ ההתנהגות של peerDependencies היא הפעם ממש ×ž×•×¦×œ×—×Ŗ. אם יש לי ב package.json של ההפריה שלי את הבלוק הבא:
"peerDependencies": {
  "react": "^17.0.2"
}
והלקוח שלי מחזיק קובׄ package.json עם בלוק כזה:
"dependencies": {
  "mylib": "file:../mylib/mylib-1.0.1.tgz",
  "react": "16.8.1"
}
אז כשהוא ×™× ×”×” ×œ×”×Ŗ×§×™×Ÿ הוא יקבל את ההודעה:
$ npm install
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: myapp@1.0.0
npm ERR! Found: react@16.8.1
npm ERR! node_modules/react
npm ERR!   react@"16.8.1" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^17.0.2" from mylib@1.0.2
npm ERR! node_modules/mylib
npm ERR!   mylib@"file:../mylib/mylib-1.0.2.tgz" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry

ToCode
1 419
        next_child = next(child for child in doc if '/'+child["key"] == pos+'/'+path[0])
    except StopIteration:
        doc.append({ "type": "d", 'key': key, 'title': path[-1], 'children': [] })
        next_child = doc[-1]

    return add_node(next_child["children"], path[1:], key, pos+'/'+path[0])
    

doc = []

for root, dirs, files in os.walk('.'):
    key = root[1:].split('/')[1:]
    node = add_node(doc, key, '/'.join(key))
    prefix = '/'.join(key) + '/' if len(key) > 0 else ''
    node.extend([{ "type": "f", "title": f, "key": f"{prefix}{f}", "children": [] } for i, f in enumerate(files)])

print(json.dumps(doc))
× ×Ŗ×—×™×œ מהחלק השני - הפונקציה os.walk: 1. מפעילים את os.walk ×‘×Ŗ×•×š for כדי ×œ×Ø×•×„ על כל הקבצים והתיקיות בצורה רקורביהית בעׄ התיקיות. 2. כל ×›× ×™×”×” לגוף הלולאה ××•×ž×Ø×Ŗ שנכנהתי ×œ×Ŗ×™×§×™×” חדשה. אני מפעיל את הפונקציה add_node כדי להוהיף ×¦×•×ž×Ŗ חדש בעׄ בדיוק במקום ×©×ž×Ŗ××™× ×œ××•×Ŗ×” ×Ŗ×™×§×™×”. פונקציית add_node ×ž×—×–×™×Ø×” את ×ž×¢×Ø×š הילדים של ×”×Ŗ×™×§×™×” שהיא הרגע הוהיפה. 3. אחרי זה אני ×ž×©×Ŗ×ž×© ×‘×ž×©×Ŗ× ×” files שחוזר ×ž××•×Ŗ×• ××™×˜×Ø×˜×•×Ø כדי להוהיף גם את כל הקבצים ולמלא ×‘××ž×¦×¢×•×Ŗ× את ×ž×¢×Ø×š הילדים. הפונקציה add_node ×ž×˜×™×™×œ×Ŗ בצורה רקורביהית ב Dictionary לפי המבנה של מילון הקבצים ומוהיפה ×Ŗ×™×§×™×” חדשה למקום הנכון. היא ×ž×©×Ŗ×ž×©×Ŗ ב key של כל אוביקט כדי ×œ×“×¢×Ŗ לאיזה × ×Ŗ×™×‘×™× לנווט ×‘×Ŗ×•×š ה Dictionary.

ToCode
1 419
# עוד דוגמה ל os.walk ב Python הפונקציה os.walk ×ž×”×¤×§×Ŗ ×“×Ø×š קלה ×œ×¢×‘×•×Ø על כל עׄ הקבצים והתיקיות החל ×ž× ×§×•×“×Ŗ ×”×Ŗ×—×œ×” ×ž×”×•×™×ž×Ŗ. בדוגמה בפוהט היום ××©×Ŗ×ž×© בה כדי ×œ×‘× ×•×Ŗ אוביקט JSON ×©×ž×Ŗ××™× לעׄ קבצים ותיקיות ×‘×¤×•×Ø×ž×˜ מהוים. ## מה אנחנו בונים × ×Ŗ×•×Ÿ עׄ קבצים ותיקיות שנראה כך:
.
ā”œā”€ā”€ a
│   ā”œā”€ā”€ b
│   │   ā”œā”€ā”€ 00
│   │   │   └── 11
│   │   │       ā”œā”€ā”€ 22
│   │   │       ā”œā”€ā”€ 33
│   │   │       └── 44
│   │   ā”œā”€ā”€ c
│   │   │   ā”œā”€ā”€ c1.txt
│   │   │   ā”œā”€ā”€ c2.txt
│   │   │   └── d
│   │   └── ff
│   │       └── gg
│   ā”œā”€ā”€ f1.txt
│   └── f2.txt
└── build_json.py
ואני רוצה להפוך אותו לאוביקט JSON שנראה כך:
[
  {
    "type": "f",
    "title": "build_json.py",
    "key": "build_json.py",
    "children": []
  },
  {
    "type": "d",
    "key": "a",
    "title": "a",
    "children": [
      {
        "type": "f",
        "title": "f1.txt",
        "key": "a/f1.txt",
        "children": []
      },
      {
        "type": "f",
        "title": "f2.txt",
        "key": "a/f2.txt",
        "children": []
      },
      {
        "type": "d",
        "key": "a/b",
        "title": "b",
        "children": [
          {
            "type": "d",
            "key": "a/b/00",
            "title": "00",
            "children": [
              {
                "type": "d",
                "key": "a/b/00/11",
                "title": "11",
                "children": [
                  {
                    "type": "d",
                    "key": "a/b/00/11/33",
                    "title": "33",
                    "children": []
                  },
                  {
                    "type": "d",
                    "key": "a/b/00/11/44",
                    "title": "44",
                    "children": []
                  },
                  {
                    "type": "d",
                    "key": "a/b/00/11/22",
                    "title": "22",
                    "children": []
                  }
                ]
              }
            ]
          },
          {
            "type": "d",
            "key": "a/b/ff",
            "title": "ff",
            "children": [
              {
                "type": "d",
                "key": "a/b/ff/gg",
                "title": "gg",
                "children": []
              }
            ]
          },
          {
            "type": "d",
            "key": "a/b/c",
            "title": "c",
            "children": [
              {
                "type": "f",
                "title": "c1.txt",
                "key": "a/b/c/c1.txt",
                "children": []
              },
              {
                "type": "f",
                "title": "c2.txt",
                "key": "a/b/c/c2.txt",
                "children": []
              },
              {
                "type": "d",
                "key": "a/b/c/d",
                "title": "d",
                "children": []
              }
            ]
          }
        ]
      }
    ]
  }
]
כדי ×©×™×Ŗ××™× לקומפוננטה שמציגה עׄ בצורה גרפית על המהך. המבנה הולך ככה: 1. האוביקט הראשי הוא ×ž×¢×Ø×š של אוביקטים 2. כל אוביקט ×‘×ž×¢×Ø×š מכיל 4 שדות: שדה type שיכול ×œ×”×™×•×Ŗ d או f כדי לציין אם זה ×Ŗ×™×§×™×” או קובׄ; שדה key שמכיל את הנתיב המלא ×œ×“×‘×Ø (והוא ייחודי בכל העׄ); שדה title שמכיל את שם הדבר ושדה בשם children שמכיל ×ž×¢×Ø×š של אוביקטים באותו מבנה בדיוק. 3. אם האוביקט הוא קובׄ אז ×ž×¢×Ø×š הילדים שלו ריק. 4. אם האוביקט הוא ×Ŗ×™×§×™×” אז ×ž×¢×Ø×š הילדים שלו מייצג את הקבצים והתיקיות שנמצאים ×‘×Ŗ×•×š ×”×Ŗ×™×§×™×”. מוזמנים ×œ× ×”×•×Ŗ ×œ×‘× ×•×Ŗ את המנגנון ואחרי זה להמשיך לקוד הדוגמה שלי. ## התוכנית עם os.walk אנחנו יכולים ×œ×›×Ŗ×•×‘ כל תוכנית שעוברת על עׄ הקבצים בצורה פשוטה ובלי ×œ×œ×›×Ŗ לאיבוד ביער. הפונקציה ×ž×—×–×™×Ø×” ××™×˜×Ø×˜×•×Ø שבכל ××™×˜×Ø×¦×™×” בוחר ×Ŗ×™×§×™×” אחרת ×•×ž×—×–×™×Ø את ×Ø×©×™×ž×Ŗ הקבצים והתיקיות באותה ×Ŗ×™×§×™×” שהוא בחר. ×”××™×˜×Ø×¦×™×” היא לפי ההדר ×”××ž×™×Ŗ×™ של הקבצים והתיקיות ולכן נוח ×œ×”×©×Ŗ×ž×© בה כדי ×œ×‘× ×•×Ŗ את אוביקט ה JSON. זה היה ×”×¤×™×Ŗ×Ø×•×Ÿ שלי:
import os, json

def add_node(doc, path, key, pos=''):
    if len(path) == 0:
        return doc

    try:

ToCode
1 419
# ×”××•×ž× ×•×Ŗ של להשיג ×“×‘×Ø×™× ×‘×œ×Ŗ×™ ××¤×©×Ø×™×™× יש ימים שאני יכול ×œ×Ø××•×Ŗ בבירור את ×”×“×Ø×š מפה לשם, אפילו אם "שם" זה מקום מאוד רחוק מאיפה שאני נמצא. אני בטוח שגם לכם יש נקודות הארה כאלה ×©×¤×Ŗ××•× ×Ø×•××™× במכה אחת הידרה של צעדים שאם רק אצליח בהם אגיע ×œ×“×‘×Ø הזה שנראה כרגע מאוד רחוק ×•×‘×œ×Ŗ×™ אפשרי. ויש ימים שבהם אני לא רואה את ×”×“×Ø×š כולה. שהבהירות × ×¢×œ×ž×Ŗ ×•×”×ž×Ø×—×§ נראה ×‘×œ×Ŗ×™ × ×™×Ŗ×Ÿ ×œ×’×™×©×•×Ø. ×”××ž×Ŗ שרוב הימים הם כאלה - ובגלל זה ×“×‘×Ø×™× מהובכים × ×Ø××™× הרבה פעמים ×‘×œ×Ŗ×™ ××¤×©×Ø×™×™×. ×”×“×Ø×š לצאת ×ž×”×¤×Ø×“×•×§×” ×›×©×Ø×•×¦×™× להשיג דבר ×‘×œ×Ŗ×™ אפשרי היא קודם כל להבין שהדבר הזה הוא כן אפשרי - פשוט מהובך. ולהשיג ×“×‘×Ø×™× מהובכים זה הרבה יותר קל מלהשיג ×“×‘×Ø×™× ×‘×œ×Ŗ×™ ××¤×©×Ø×™×™×. וגם די קל להבין שמשהו הוא אפשרי פשוט מהובך, פשוט ×ž×”×Ŗ×›×œ×™× על אנשים ××—×Ø×™× שהצליחו אותו או על ×”×”×™×”×˜×•×Ø×™×” שלכם בה ×”×¦×œ×—×Ŗ× ×“×‘×Ø×™× דומים. אני יודע, אנחנו ×Ø×’×™×œ×™× לחשוב שמשהו הוא אפשרי רק אם אנחנו ×Ø×•××™× את ×”×“×Ø×š המלאה מכאן לשם. אבל זאת ×¤×Ø×™×•×•×™×œ×’×™×” שאנשים שלומדים לבד לא יכולים להמוך עליה. הצעד השני הוא להבין ×©×”×“×Ø×š להשיג ×“×‘×Ø×™× מהובכים היא קשה, ארוכה ×•×ž×”×•×‘×›×Ŗ (נו, אחרת לא היינו ×¦×Ø×™×›×™× פוהט על זה), ורוב הזמן שנבלה בה יהיה בימים של ערפל, בימים בהם אי אפשר לדמיין אפילו את ×”×“×Ø×š מכאן לשם. בימים בהם לא נראה שיש קשר בין המשימה שאתה עושה עכשיו לבין הדבר ×”×‘×œ×Ŗ×™ אפשרי שאתה רוצה להשיג. ×”×“×Ø×š ללמוד ×ž×™×•×ž× ×•×Ŗ חדשה היא כמו × ×”×™×¢×” על כביש חשוך ×•×¢×Ø×¤×™×œ×™. אפשר ×œ×Ø××•×Ŗ כמה ×ž×˜×Ø×™× קדימה - זאת המשימה ×”×œ×™×ž×•×“×™×Ŗ הנוכחית שאתה עובד עליה - אבל קשה מאוד ×œ×Ø××•×Ŗ איך אותה משימה מביאה בהוף ×”×Ŗ×”×œ×™×š ×œ×Ŗ×•×¦××” הרצויה. ובגלל זה כל כך קשה ×œ×”×Ŗ×ž×™×“ במשימה הנוכחית, ובמיוחד אם היא ×ž×©×¢×ž×ž×Ŗ, קשה, ×ž×Ŗ×”×›×œ×Ŗ, מכעיהה או יוצרת רגשות שליליים ××—×Ø×™× מכל הוג. וכן ×ž×©×™×ž×•×Ŗ קשות × ×•×˜×•×Ŗ ×œ×¢×©×•×Ŗ את זה. לכן ×”××•×ž× ×•×Ŗ של להשיג ×“×‘×Ø×™× ×‘×œ×Ŗ×™ ××¤×©×Ø×™×™× יכולה ×œ×”×”×Ŗ×›× בשתי נקודות: 1. כשיש רגע של בהירות, או אם יש חבר שכבר כתב תוכנית ×©××Ŗ× יכולים ×œ×§×—×Ŗ - תבנו לכם תוכנית עבודה ×ž×”×•×“×Ø×Ŗ, ×ž×¤×•×Ø×˜×Ŗ וכתובה. היא חייבת ×œ×”×™×•×Ŗ כתובה כי ×ž×”×Ø××© היא ×Ŗ×™×ž×—×§ לכם ×ž×”×Ø מאוד. 2. בכל שאר הזמן תעבדו ×Ŗ×ž×™×“ על המשימה הבאה בתוכנית עבודה. ×ž×•×Ŗ×Ø להחליף תוכנית עבודה רק ברגע של בהירות או אם ×”×™×™×ž×Ŗ× את כל ×”×ž×©×™×ž×•×Ŗ שבה. שיעור אחרי שיעור, משימה אחרי משימה וצעד אחרי צעד הם ×”×“×Ø×š שלנו להשיג גם את ×”×“×‘×Ø×™× ×©× ×Ø××™× היום ×‘×œ×Ŗ×™ ××¤×©×Ø×™×™×.

ToCode
1 419
1. פוד הוא ×§×•× ×˜×™×™× ×Ø. או ×œ×¤×—×•×Ŗ ×œ×Ŗ×§×•×¤×” הקרובה יהיה לנו נוח מאוד לחשוב עליו בתור ×§×•× ×˜×™×™× ×Ø. פוד זה משהו שרׄ על שרת ×ž×Ŗ×•×š אימג', ×•×§×•×‘×Ø× ×˜×™×” יוודא שאותו פוד ימשיך ×œ×Ø×•×„ כל עוד ×¦×Ø×™×š אותו ואם הוא ×ž×Ŗ×Ø×”×§ ×§×•×‘×Ø× ×˜×” ×™×Ø×™× אחד חדש במקומו. 2. דיפלוימנט זה מה שיוצר את הפודים, ×›×œ×•×ž×Ø זאת ×”×Ŗ×§× ×” של תוכנה. ×ž×Ø×’×¢ ×©×©×œ×—×Ŗ× Deployment ×œ×§×•×‘×Ø× ×˜×™×” הוא (היא?) ×™× ×”×” ×œ×™×¦×•×Ø ×§×•× ×˜×™×™× ×Ø×™× (פודים) ×ž×Ŗ×•×š התיאור שמופיע ב Deployment. 3. הרביה זאת ×”×“×Ø×š שלנו ×œ×”×Ŗ×—×‘×Ø לפוד. תזכרו ×©×œ×§×•×‘×Ø× ×˜×™×” יש קלאהטר שלם של ×©×Ø×Ŗ×™× עליו הוא יכול ×œ×”×Ø×™×„ את הפוד שלכם, וגם אם ישעמם לו או אם אחד ×”×©×Ø×Ŗ×™× יהיה עמוה ×§×•×‘×Ø× ×˜×™×” יוכל להזיז את הפוד ×ž×©×Ø×Ŗ לשרת. הרביה זה הוג של מיפוי ×¤×•×Ø×˜×™× ×©××•×ž×Ø ×©×›×©×ž×Ŗ×—×‘×Ø×™× ×œ×¤×•×Ø×˜ מהוים ב IP הציבורי של ×”×§×œ××”×˜×Ø אז ×§×•×‘×Ø× ×˜×™×” ×¦×Ø×™×š ×œ×—×‘×Ø ××Ŗ×›× לפוד ×”×ž×Ŗ××™×, איפה שהוא לא רׄ כרגע. כל אחד מהשלושה יכול ×œ×”×™×•×Ŗ מיוצג על ידי קובׄ YAML ×©×ž×Ŗ××Ø את המאפיינים שלו. ראינו כבר קובׄ YAML עבור Deployment, ואם ××Ŗ× ×”×§×Ø× ×™× אז הנה קובׄ YAML פשוט עבור הרביה:
apiVersion: v1
kind: Service
metadata:
  annotations:
    kompose.cmd: kompose convert
    kompose.version: 1.25.0 (a70f80cc)
  creationTimestamp: null
  labels:
    io.kompose.service: nginx
  name: nginx
spec:
  type: NodePort
  ports:
    - name: "80"
      port: 80
      targetPort: 80
  selector:
    io.kompose.service: nginx
status:
  loadBalancer: {}
הקובׄ ×ž×Ŗ××Ø הרביה ×©×ž×Ŗ×—×‘×Ø ל Deployment של ה nginx שיצרנו קודם. ×”×ž×¤×Ŗ×— להבין את הקובׄ הוא הבלוק ×©×ž×Ŗ×—×™×œ במילה selector, שקובע לאיזה תוכנית ההרביה הזה ×¦×Ø×™×š ×œ×—×‘×Ø אותנו, ו port שקובע לאיזה ×¤×•×Ø×˜ ×¦×Ø×™×š ×œ×”×Ŗ×—×‘×Ø שם. # ×§×•×‘×Ø× ×˜×™×” והענן: ×”×Ŗ×§× ×™ קלט ופלט עד לפה ראינו ×©×§×•×‘×Ø× ×˜×™×” היא (הוא?) ×ž×¢×Ø×›×Ŗ הפעלה ×œ×§×œ××”×˜×Ø×™×. ראינו שהתפקיד שלה הוא להפעיל תוכניות, ×›×œ×•×ž×Ø אימג'ים, ×•×œ×™×™×¦×Ø מהם ×§×•× ×˜×™×™× ×Ø×™× ולוודא ×©××•×Ŗ× ×§×•× ×˜×™×™× ×Ø×™× ממשיכים ×œ×Ø×•×„ ומקבלים את משאבי השרת שהם ×¦×Ø×™×›×™×. היבט נוהף בו ×× ×œ×•×’×™×™×Ŗ ×ž×¢×Ø×›×Ŗ ההפעלה תעזור לנו להבין את ×§×•×‘×Ø× ×˜×™×” הוא הגישה ×œ×”×Ŗ×§× ×™ קלט ופלט. ×ž×¢×Ø×›×Ŗ הפעלה כזכור לכם ×ž×—×‘×Ø×Ŗ את התוכניות שרצות על המחשב עם ×”×—×•×ž×Ø×” של המחשב ×‘××ž×¦×¢×•×Ŗ ×“×Ø×™×™×‘×Ø×™×. תוכנית לא כותבת ישירות לדיהק אלא ×‘×Ŗ×™×•×•×š ×ž×¢×Ø×›×Ŗ ההפעלה. תוכנית לא קוראת ישירות ×ž×”×ž×§×œ×“×Ŗ אלא ×‘×Ŗ×™×•×•×š ×ž×¢×Ø×›×Ŗ ההפעלה. באותו האופן ×§×•×‘×Ø× ×˜×™×” ×ž×Ŗ×•×•×š את הגישה של ×”×§×•× ×˜×™×™× ×Ø×™× למשאבים חיצוניים ×©× ×©×ž×Ø×™× בענן. לדוגמה: 1. ×ž×¢×Ø×›×Ŗ הקבצים של ×§×•× ×˜×™×™× ×Ø לא שורדת ×›×©×”×§×•× ×˜×™×™× ×Ø נהגר. ×‘×Ŗ×™×•×•×š ×§×•×‘×Ø× ×˜×™×” ×”×§×•× ×˜×™×™× ×Ø יכול לקבל Volume שזה מקום על הדיהק שאפשר ×œ×›×Ŗ×•×‘ אליו והמידע ×™×™×©×ž×Ø גם ×›×©×”×§×•× ×˜×™×™× ×Ø ייהגר. 2. ×§×•× ×˜×™×™× ×Ø יכול לקבל מידע הודי ×‘××ž×¦×¢×•×Ŗ מנגנון Secrets של ×§×•×‘×Ø× ×˜×™×”. 3. ×§×•× ×˜×™×™× ×Ø יכול לקבל ×ž×©×Ŗ× ×™ הביבה ×©×ž×•×¢×‘×Ø×™× אליו ×ž×Ŗ×•×š ×§×•×‘×Ø× ×˜×™×”. ×§×œ××”×˜×Ø×™× שונים יכולים לממש את ×”×”×Ŗ×§× ×™× החיצוניים ×‘×“×Ø×›×™× שונות: לדוגמה קלאהטר ×§×•×‘×Ø× ×˜×™×” שרׄ על ענן של Azure יכול ×œ×—×‘×Ø Volume לכונן אחהון בענן של אזור, ×•×§×œ××”×˜×Ø אחר שרׄ על אמזון יחבר את ה Volume לכונן אחהון בענן של אמזון. ×ž×‘×—×™× ×Ŗ התוכנית שלנו שרצה ×‘×Ŗ×•×š ×”×§×œ××”×˜×Ø הגישה היא זהה בשני ×”×ž×§×Ø×™×. אנחנו מקבלים Volume ×•×§×•×‘×Ø× ×˜×™×” אחראי על מיפוי אותו Volume ×œ×”×Ŗ×§×Ÿ האיחהון החיצוני. ## איך ממשיכים מכאן ואם ההקדמה הזאת עשתה לכם חשק להמשיך וללמוד ×§×•×‘×Ø× ×˜×™×” ×Ŗ×©×ž×—×• לשמוע שיש אינהוף ×ž×“×Ø×™×›×™× טובים ברשת כולל כאלה שיתנו לכם ×œ×Ŗ×Ø×’×œ בצורה ××™× ×˜×Ø×§×˜×™×‘×™×Ŗ. אני ממליׄ ×œ×”×Ŗ×—×™×œ ×ž×”×§×™×©×•×Ø הזה: https://kubernetes.io/docs/tutorials/kubernetes-basics/ שכולל הידרה של 6 ×˜×•×˜×•×Ø×™××œ×” ××™× ×˜×Ø×§×˜×™×‘×™×™× לעבודה עם ×§×•×‘×Ø× ×˜×™×” והתקנת יישומים ×‘××ž×¦×¢×•×Ŗ×•. עמוד התיעוד הראשי של ×§×•×‘×Ø× ×˜×” הוא גם מקום לימוד מצוין אם ××Ŗ× אוהבים ×œ×§×Ø×•× ×ž×’×™×œ×•×Ŗ של טקהט (נו אל תדאגו יש גם ×Ŗ×ž×•× ×•×Ŗ). קישור: https://kubernetes.io/docs/concepts/

ToCode
1 419
# מושגים בהיהיים ×‘×§×•×‘×Ø× ×˜×™×” ×©×ž×¢×Ŗ× על ×§×•×‘×Ø× ×˜×™×” אבל לא בטוחים מה זה? ×Ø×•×¦×™× ללמוד ולא יודעים אפילו איפה ×œ×”×Ŗ×—×™×œ? הפוהט הזה בשבילכם ואני מקווה שאצליח ×œ×¢×©×•×Ŗ קצת הדר באוקיינוה שנקרא ×§×•×‘×Ø× ×˜×™×”, ×œ×¤×—×•×Ŗ ×‘×”×Ŗ×—×œ×” שלו. ## ×§×•×‘×Ø× ×˜×™×” היא ×ž×¢×Ø×›×Ŗ הפעלה ×œ×§×œ××”×˜×Ø×™× ××Ŗ× יודעים כבר שלמחשבים יש ×ž×¢×Ø×›×•×Ŗ הפעלה: יש Windows, Linux ו OS/X; לטלפונים יש את Android ו iOS ועוד כמה וגם ×ž×›×©×™×Ø×™ IOT הרבה פעמים מגיעים עם איזושהי ×ž×¢×Ø×›×Ŗ הפעלה ×ž×‘×•×”×”×Ŗ לינוקה. מה שלא כל כך אינטואיטיבי הוא המחשבה שאפשר ×œ×™×™×¦×Ø ×ž×¢×Ø×›×Ŗ הפעלה גם למשהו שהוא לא מחשב. למשהו גדול יותר ממחשב. ×‘×ž×§×Ø×” שלנו לאוהף של ×©×Ø×Ŗ×™×. אוהף של ×©×Ø×Ŗ×™× נקרא Cluster ×•×§×•×‘×Ø× ×˜×™×” הוא (היא?) ×ž×¢×Ø×›×Ŗ הפעלה ×œ×§×œ××”×˜×Ø×™×. ×ž×¢×Ø×›×Ŗ הפעלה ×Ø×’×™×œ×” של מחשב אחראית על ×”×¤×¢×œ×Ŗ תוכניות וניהול ×•×—×œ×•×§×Ŗ משאבי ×”×ž×¢×Ø×›×Ŗ ×œ×Ŗ×•×›× ×™×•×Ŗ שרצות. היא גם דואגת שתוכניות לא ידרהו אחת את השניה, ×•×ž×”×¤×§×Ŗ ×œ×Ŗ×•×›× ×™×•×Ŗ גישה קלה ואחידה ×œ×”×Ŗ×§× ×™ הקלט פלט של המחשב. ×›×œ×•×ž×Ø אם יש לי תוכנית שכתובה ×œ×ž×¢×Ø×›×Ŗ הפעלה Windows, אז זה לא משנה לה איזה הוג ×ž×§×œ×“×Ŗ ×ž×—×•×‘×Ø×Ŗ למחשב או אפילו אם זו ×ž×§×œ×“×Ŗ ××œ×—×•×˜×™×Ŗ. התוכנית ×ž×§×‘×œ×Ŗ את הקלט ×‘××ž×¦×¢×•×Ŗ ×”×Ŗ×™×•×•×š של ×ž×¢×Ø×›×Ŗ ההפעלה ויכולה לעבוד באותה צורה עם כל ×”×ž×§×œ×“×•×Ŗ. ×ž×¢×Ø×›×Ŗ הפעלה של קלאהטר ×œ×•×§×—×Ŗ קונהפט דומה, ×•×ž××¤×©×Ø×Ŗ לנו ×œ×›×Ŗ×•×‘ "תוכניות" שרצות על ×”×§×œ××”×˜×Ø. תוכנית שרצה על קלאהטר ×Ŗ×”×™×” ×‘×“×Ø×š כלל הוג של הרביה שמקבל בקשות ושולח תשובות - כמו Web Application או בהיה × ×Ŗ×•× ×™×. ×§×•×‘×Ø× ×˜×™×” ×Ŗ×¤×¢×™×œ את היישומים האלה, תדאג לחלק להם את משאבי ×”×§×œ××”×˜×Ø - ×›×œ×•×ž×Ø ×Ŗ×—×œ×™×˜ מי ירוׄ על איזה שרת ואיזה חלק ×ž×”×©×Ø×Ŗ הוא יקבל - ותדאג ×œ×”×©××™×Ø ××•×Ŗ× בחיים ולהפעיל ××•×Ŗ× מחדש אם אחד מהם ×ž×Ŗ×Ø×”×§. וכמו שתוכנית ×Ø×’×™×œ×” לא צריכה ×œ×”×›×™×Ø את ×”×—×•×ž×Ø×” עצמה עליה היא רצה, כי היא ×Ŗ×ž×™×“ עובדת ×‘×Ŗ×™×•×•×š ×ž×¢×Ø×›×Ŗ ההפעלה, כך תוכנית שרצה ×‘×Ŗ×•×š ×§×•×‘×Ø× ×˜×™×” לא חייבת ×œ×”×›×™×Ø את ×”×©×Ø×Ŗ×™× עצמם עליהם היא רצה, ויכולה להניח שהם ×ž×Ŗ× ×”×’×™× בצורה ×ž×”×•×™×ž×Ŗ - לפי הממשק שהתוכנית ×ž×§×‘×œ×Ŗ ×ž×§×•×‘×Ø× ×˜×™×”, ×›×œ×•×ž×Ø ×ž×ž×¢×Ø×›×Ŗ ההפעלה. ## תוכניות הן אימג'ים, ×Ŗ×”×œ×™×›×™× הם ×§×•× ×˜×™×™× ×Ø×™× כמו ×©×ž×¢×Ø×›×Ŗ הפעלה של מחשבים יודעת ×œ×§×—×Ŗ קבצי הפעלה - לדוגמה ב Windows קבצי EXE - ולהפעיל ××•×Ŗ×, ×›×œ×•×ž×Ø ×œ×™×¦×•×Ø מהם ×Ŗ×”×œ×™×›×™× על המחשב, כך ×§×•×‘×Ø× ×˜×™×” יודעת ×œ×§×—×Ŗ קבצי הפעלה שהם OCI Images ×•×œ×™×¦×•×Ø מהם ×Ŗ×”×œ×™×›×™× שהם Containers. אימג' הוא כל מה ×©××Ŗ× ×ž×›×™×Ø×™× מעבודה עם Docker או Podman. זה מידע בינארי ×©×ž×Ŗ××Ø אפליקציה ×ž×”×•×™×ž×Ŗ ואת כל ×”×Ŗ×œ×•×™×•×Ŗ של אותה אפליקציה. אימג'ים מאוחהנים ב Registries וגם לפני ×§×•×‘×Ø× ×˜×™×” ידענו להפעיל ×§×•× ×˜×™×™× ×Ø ×ž×Ŗ×•×š אימג' עם דוקר לדוגמה ×‘××ž×¦×¢×•×Ŗ ×”×¤×¢×œ×Ŗ:
$ docker run hello-world
×§×•×‘×Ø× ×˜×™×” בתור ×ž×¢×Ø×›×Ŗ הפעלה יודע (יודעת?) ×œ×§×—×Ŗ אימג'ים כמו ה hello-world שלנו ×•×œ×”×Ø×™×„ ××•×Ŗ× על ×”×§×œ××”×˜×Ø, ×›×œ×•×ž×Ø ×œ×‘× ×•×Ŗ מהם ×§×•× ×˜×™×™× ×Ø ×•×œ×Ŗ×Ŗ ×œ××—×Ŗ ×”×ž×›×•× ×•×Ŗ ×‘×§×œ××”×˜×Ø ×œ×”×Ø×™×„ את ×”×§×•× ×˜×™×™× ×Ø הזה. ×§×•×‘×Ø× ×˜×™×” גם ×Ŗ×©×™× לב אם ×”×§×•× ×˜×™×™× ×Ø ×ž×Ŗ×Ø×”×§ ותדע להפעיל ×§×•× ×˜×™×™× ×Ø חדש ×ž××•×Ŗ×• אימג'. ×‘×ž×¢×Ø×›×Ŗ הפעלה ×Ø×’×™×œ×” אנחנו ×ž×©×Ŗ×ž×©×™× בתוכנת Installer כדי ×œ×”×Ŗ×§×™×Ÿ את התוכניות שלנו. זה לא נדיר ×œ×”×•×Ø×™×“ ×ž×”×Ø×©×Ŗ קובׄ ×‘×”×™×•×ž×Ŗ msi, ×œ×”×Ø×™×„ אותו וכך לקבל תוכנה כזאת או אחרת זמינה לנו על המחשב. ×‘×§×•×‘×Ø× ×˜×™×” ×”×”×Ŗ×§× ×” ×ž×Ŗ×‘×¦×¢×Ŗ ×‘××ž×¦×¢×•×Ŗ קבצי טקהט ×‘×¤×•×Ø×ž×˜ YAML ×©×ž×Ŗ××Ø×™× לקלאהטר מה האימג' שאנחנו ×Ø×•×¦×™× ×œ×”×Ŗ×§×™×Ÿ ומה דרישות ×”×ž×¢×Ø×›×Ŗ שהוא ×¦×Ø×™×š. לדוגמה הקובׄ הבא הוא YAML ×©×ž×’×“×™×Ø Deployment (שזו ×”×Ŗ×§× ×”) של אימג' של שרת הווב nginx:
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    kompose.cmd: kompose convert
    kompose.version: 1.25.0 (a70f80cc)
  creationTimestamp: null
  labels:
    io.kompose.service: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      io.kompose.service: nginx
  strategy: {}
  template:
    metadata:
      annotations:
        kompose.cmd: kompose convert
        kompose.version: 1.25.0 (a70f80cc)
      creationTimestamp: null
      labels:
        io.kompose.service: nginx
    spec:
      containers:
        - image: nginx
          name: nginx
          ports:
            - containerPort: 80
          resources: {}
      restartPolicy: Always
status: {}
## פודים, דיפלומנטה ×•×”×Ø×‘×™×”×™× שלושה מושגים שכדאי ×œ×”×›×™×Ø כבר ×ž×Ŗ×—×™×œ×Ŗ העבודה שלכם עם ×§×•×‘×Ø× ×˜×” הם Pod, Deployment ו Service (יש עוד הרבה, אבל את ×©×œ×•×©×Ŗ אלה נצטרך ממש מהשניה הראשונה):

ToCode
1 419
הי הקישור ×œ×§×Ø×™××” ×ž×”××Ŗ×Ø לא עבד טוב היום זה הקישור https://www.tocode.co.il/blog/2021-12-css-sticky-overflow

ToCode
1 419
# היום ×œ×ž×“×Ŗ×™: CSS Sticky ו overflow לא הולכים טוב יחד מאפיין CSS Sticky הוא ×”×“×Ø×š הכי קלה היום ×œ×”×’×“×™×Ø שפה עליון מהעמוד ימשיך ×œ×œ×•×•×Ŗ אותנו כשאנחנו גוללים למטה, ובעצם "יידבק" לראש העמוד. הוא נוח במיוחד כשיש לכם טבלה ×•××Ŗ× ×Ø×•×¦×™× ששורת הכותרת ×Ŗ×ž×©×™×š ×œ×œ×•×•×Ŗ את הגולש גם אם הוא גולל למטה את השורות עצמן. מה שמיוחד ב sticky בניגוד ×œ×”×’×“×Ø×Ŗ overflow: scroll על הטבלה זה שאנחנו לא ×ž×™×™×¦×Ø×™× שני פהי גלילה (אחד חיצוני לעמוד והשני פנימי לטבלה) אלא ×ž×©×Ŗ×ž×© גולל בפה הגלילה ×”×Ø×’×™×œ החיצוני של העמוד וכששורת הכותרת של הטבלה מגיעה לחלק העליון של העמוד היא פשוט נדבקת לשם. בקיצור הוהפתי את ההגדרות ×”×ž×Ŗ××™×ž×•×Ŗ ל position: sticky בדיוק כמו בתיעוד וצפיתי באימה כששום דבר לא עבד. הנה הקוד, ×Ŗ×—×™×œ×” ה HTML ואחריו ה CSS (דמיינו את זה עם ×ž××•×Ŗ שורות):
<div class="root">
<table>
  <thead>
    <tr>
    <th>name</th>
    <th>hair color</th>
    <th>city</th>
    <th>gender</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>bob</td>
      <td>blue</td>
      <td>foo</td>
      <td>agender</td>
    </tr>
    <tr>
      <td>bob</td>
      <td>blue</td>
      <td>foo</td>
      <td>agender</td>
    </tr>
</tbody>
<table>
</div>
.root {
  overflow: hidden;
}
thead th {
  position: sticky;
  top: 0;
  background: #d2d2d2;  
  padding: 2px 5px 2px 0;
  
}

table {
  border-collapse: collapse;
}
ובקודפן: <iframe height="300" style="width: 100%;" scrolling="no" title="Untitled" src="https://codepen.io/ynonp/embed/qBPqXNQ?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen <a href="https://codepen.io/ynonp/pen/qBPqXNQ"> Untitled</a> by Ynon Perek (<a href="https://codepen.io/ynonp">@ynonp</a>) on <a href="https://codepen.io">CodePen</a>. </iframe> וקל ×œ×Ø××•×Ŗ שגלילה של המהך לא ×‘××ž×Ŗ ×ž×©××™×Ø×” את שורת הכותרת "דבוקה" לראש העמוד. מה קורה פה? התשובה ×ž×”×Ŗ×Ŗ×Ø×Ŗ במשפט הבא ×ž×Ŗ×•×š MDN: > Note that a sticky element "sticks" to its nearest ancestor that has a "scrolling mechanism" (created when overflow is hidden, scroll, auto, or overlay) או בעברית - בגלל שמעל הטבלה יש לי div עם מאפיין overflow: hidden, ×œ×ž×Ø×•×Ŗ של div הזה אין ×”×’×‘×œ×Ŗ גובה והוא לא ×ž×™×™×¦×Ø גלילה ×¤× ×™×ž×™×Ŗ, ה sticky של הטבלה יהיה דביק ביחה אליו ולא ביחה ל body. במילים אחרות שורת הכותרת של הטבלה אכן נדבקת לחלק העליון, פשוט לחלק העליון של ה div שעוטף אותה, והוא זז למעלה מחוׄ לחלק שאנחנו ×Ø×•××™×. ×”×¤×™×Ŗ×Ø×•×Ÿ? כמו ×Ŗ×ž×™×“ פשוט כשיודעים. כל פעם ×©×Ø×•×¦×™× ×œ×”×©×Ŗ×ž×© ב position: sticky יש לוודא שאין מעליכם אלמנט עם overflow. הנה הקודפן ×”×ž×Ŗ×•×§×Ÿ: <iframe height="300" style="width: 100%;" scrolling="no" title="Untitled" src="https://codepen.io/ynonp/embed/gOGLxrO?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true"> See the Pen <a href="https://codepen.io/ynonp/pen/gOGLxrO"> Untitled</a> by Ynon Perek (<a href="https://codepen.io/ynonp">@ynonp</a>) on <a href="https://codepen.io">CodePen</a>. </iframe>

ToCode
1 419
# ×ž×Ŗ×™ ×ž×Ŗ×—×™×œ×™× ואיפה מוצאים זמן? אלה שתי ×©××œ×•×Ŗ שונות. אל תנהו ×œ×—×‘×Ø ביניהן. הרבה פעמים אנחנו חושבים על משימה ×œ×™×ž×•×“×™×Ŗ ומבינים כמה השקעה ×¦×Ø×™×š בשביל לבצע אותה, ומבינים שאין לנו עכשיו את המשאבים והזמן ×œ×¢×©×•×Ŗ את זה, ואז דוחים את ×”×”×Ŗ×—×œ×”. נכון, אני ××•×ž×Ø לעצמי, אני יכול למצוא שעה בשבוע ללמוד CSS, אבל אני גם יודע ששעה בשבוע לא תהפיק בשביל להגיע להישג ×ž×©×ž×¢×•×Ŗ×™ אז עדיף להשקיע את השעה הפנויה שלי בשבוע במשהו אחר. התוצאה של זה היא דחיה אינהופית של ×“×‘×Ø×™× שאנחנו ×Ø×•×¦×™× ×œ×¢×©×•×Ŗ כי אף פעם אי אפשר למצוא עשר שעות בשבוע להשקיע בלימוד CSS. מי שידפדף מהפיק אחורה בבלוג פה יגלה שלפני שכתבתי כל יום כתבתי פעמיים בשבוע, ולפני זה כתבתי פעם בשבוע. ההחלטה ×œ×”×Ŗ×—×™×œ ×œ×›×Ŗ×•×‘ בלוג לא ×”×™×Ŗ×” ×ž×Ŗ××¤×©×Ø×Ŗ אם ×ž×Ø××© ×”×™×™×Ŗ×™ חושב ×©×¦×Ø×™×š ×œ×›×Ŗ×•×‘ פוהט כל יום. באותה נקודה שרק ×”×Ŗ×—×œ×Ŗ×™, כתיבה כל יום נראתה לי כמו השקעה ×ž×˜×•×Ø×¤×Ŗ. פעם בשבוע היה משהו הרבה יותר הביר. הדעה שלנו לגבי נושאים, ×—×œ×•×§×Ŗ זמנים ×•×”×™×›×•×œ×Ŗ למצוא זמן ×œ×“×‘×Ø×™× ×ž×©×Ŗ× ×” עם הזמן. ככל שאנחנו עמוק יותר ×‘×Ŗ×•×š ×¤×Ø×•×™×§×˜ כך קל יותר להמשיך ולמצוא יותר זמן עבורו. ×”×Ŗ×—×œ×” דורשת הרבה יותר אנרגיה מההמשך ושעה ×‘×Ŗ×—×™×œ×Ŗ ×”×¤×Ø×•×™×§×˜ היא הרבה יותר "קשה" משעה באמצע שלו. אם יש לכם היום שעה ביום ללמוד CSS זה מהמם. אבל אם ××Ŗ× ×Ø×•×¦×™× ×œ×“×¢×Ŗ CSS טוב יותר ויש לכם רק שעה בשבוע בשביל זה - אל תחכו. ככל ×©×Ŗ×Ŗ×§×“×ž×• עם הלימוד תראו ששעה בשבוע הופכת ×œ×©×¢×Ŗ×™×™×, ×©×¢×Ŗ×™×™× ×œ××Ø×‘×¢ ובהוף מגיעים לשעה ביום ×‘×§×œ×•×Ŗ. ×ž×Ŗ×—×™×œ×™× היום. את הזמן אפשר למצוא בהמשך.