אם יש משהו שקל למתכנתי Node להסכים עליו זה ש npm שבור. הבעיות המרכזיות בו הן:
מלחמת שמות נוראית במאגר המרכזי, שמובילה לרישום חבילות פיקטיביות וחבילות מזיקות (כן כמו 17 חבילות שונות לגניבת טוקנים של דיסקורד)
הגדרה "גמישה" של גירסאות ב package.json וקובץ package-lock.json שחצי מהאנשים מוחקים אותו כל פעם שיש קונפליקט.
תלות במאגר מרכזי לכל בניה (היוש left-pad)
התקנת חבילות שכוללות אינסוף זבל בנוסף לקבצים שרצית, ורק מנפחות את node_modules
(היוש readline)
דינו, הניסיון השני של ריאן דל ליצור סביבת ריצה ל JavaScript מחוץ לדפדפן, מתמודד עם ניהול חבילות חיצוניות בצורה מובנית, מבוזרת ודי מעניינת.
דינו משתמש ב import ולא ב require, אבל השוס הגדול הוא שבמקום להעביר ל import שם של חבילה אנחנו מעבירים את ה URL המלא אליה. כלומר בשביל להשתמש ב lodash בתוכנית דינו אני אכתוב:
import * as _ from 'https://cdn.skypack.dev/-/lodash-es@v4.17.21-rDGl8YjBUjcrrAbjNrmo/dist=es2019,mode=imports/optimized/lodash-es.js';
const squares = _.map(_.range(10), (x) => x * x);
console.log(squares);
וזה כבר פותר חלק גדול מהבעיות של npm:
בגלל שאני מעביר URL, לא צריך ללכת מכות על שמות.
הגדרת הגירסה היא חלק מה URL והיא מאוד ספציפית, כמו בתגיות ה script שהיו לנו פעם בקבצי HTML, לפני שעברנו לוובפאק. וגם אין ולא צריך package.json. גם לא צריך ללמוד את ההבדל בין devDependencies ל peerDependencies ול dependencies רגילים. מה שעושים לו import נטען.
לא צריך מאגר מרכזי.
מורידים רק מה שמשתמשים בו ולא חבילה שלמה
בעיה שכבר אפשר לראות במנגנון הזה היא מה קורה כשהתוכן שב URL משתנה, והאם זה לא ישבור לי את כל הפרויקט. אז האמת שגם על זה הם חשבו ואפשר ליצור קובץ נעילה ששומר hash של המודול, ואז בהורדה הבאה לוודא שה hash לא השתנה. אם נניח קראתי לתוכנית שלי demo.js
אז על המכונה שלי במצב פיתוח אני אכתוב:
$ deno cache --lock=lock.json --lock-write -r demo.js
וזה ייצור לי קובץ בשם lock.json על המחשב עם התוכן:
{
"https://cdn.skypack.dev/-/lodash-es@v4.17.21-rDGl8YjBUjcrrAbjNrmo/dist=es2019,mode=imports/optimized/lodash-es.js": "4a1b35d34b5e0d3ae68aa46ddaabb9700ccecb75b830974db7c46a271f10daa8"
}
עכשיו כשאני אעביר את התוכנית למכונה אחרת אני מעביר איתה את קובץ ה lock.json שיצרתי, ומפעיל שם:
$ deno cache --lock=lock.json -r 03-with-lodash.js
ודינו יוריד את כל החבילות החיצוניות וישווה את ה hash-ים שלהן מול מה שכתוב בקובץ המנעול. אחרי זה בדרך כלל נריץ עם:
$ deno run --lock=lock.json --cached-only 03-with-lodash.js
וזה מוודא שכל החבילות נטענות רק מה cache ושום דבר חדש לא יורד מהרשת.
האם זה יתפוס? זאת השאלה הגדולה. במעבר לדינו נצטרך להתרגל לחפש שוב URL-ים מלאים ב cdn-ים במקום פשוט להתקין עם npm install
ושם קצר של חבילה. לאורך זמן הגישה של דינו נשמעת לי יותר יציבה, אבל יהיה קשה להיפרד מ npm install lodash
.