מדריך Node.js: שימוש ב-require

כך כוללים קבצי מודולים עם require ב-Node.js
Node.js Logo

במאמר הקודם דיברנו על דרכים שונות לכתוב פונקציה אסינכרונית ב-node.js. על מנת להמחיש את העניין, השתמשתי במודול של Node.js שנקרא fs. מודולים הם בעצם ספריות קוד (לא שונות לצורך העניין מתוספים של jQuery) שאנו חייבים לקרוא להן אם אנו משתמשים בהן בקוד שלנו. יש ספריות שבאות עם Node.js באופן מובנה – כמו fs למשל, ויש כאלו שצריך להוריד ולהתקין.

על מנת שמודול יהיה זמין ונוכל להשתמש בו, אנו צריכים לכלול אותו ב-require. איך זה נראה? ראינו כבר קודם – בדיוק ככה:


var fs = require('fs');

מה בעצם קורה כשאנחנו עושים require? קובץ ה-JavaScript נקרא, מורץ וחוזר אלינו אובייקט שנקרא export. נמחיש את העניין אם נכתוב מודול משלנו. כאשר אנו כותבים מודול משלנו וקוראים לו, אנחנו חייבים לשים /. לפני השם שלו (אם הקריאה מתבצעת מאותה תיקיה) כיוון שאחרת ה-require חושב שמדובר במודול ליבה ואז הטעינה תכשל.

ניצור קובץ ששמו הוא testModule.js. יהיה בו את הקוד הבא:


console.log("evaluating testModule.js");

var invisible = function () {
    console.log("invisible");
}

exports.message = "hi";

exports.say = function () {
    console.log(message);
}

באותה תיקיה אני אצור קובץ test.js ואכניס לתוכו את הטקסט הזה:


var tm = require('./testModule.js');

אם אני אריץ את test.js (זוכרים איך? nodejs test.js). אני אקבל את הפלט הזה:


evaluating testModule.js

זה כי ה-require לוקח את הקוד ומריץ אותו, לפיכך שורת ה-console.log תפעל ברגע שאני עושה require.

אם אני אדפיס את משתנה ה-tm שמקבל את מה שה-require מחזיר, זה מה שאני אקבל:


{ message: 'hi', say: [Function] }

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


var tm = require('./testModule.js');

console.log(tm);

console.log(tm);

tm.message = "Ran the great!";

var tm2 = require('./testModule.js');

console.log(tm2);

מה לפי דעתכם הפלט יהיה? התשובה היא:


evaluating testModule.js
{ message: 'hi', say: [Function] }
{ message: 'hi', say: [Function] }
{ message: 'Ran the great!', say: [Function] }

זה פשוט בגלל ש-require עושה caching. בגלל זה, אגב, אפשר לעשות לפעמים טעינה מעגלית (a טוען את b שטוען את c שטוען את a).

אם אנו מספקים ל-require תיקיה ולא קובץ js, אז require יחפש את package.json כדי לטעון את הקבצים שמפורטים ב-json הזה או את index.js אם package.json לא נמצא.
אם אנו עושים require לקובץ json, אז נקבל חזרה את קובץ ה-json אחרי שנעשה לו פרסינג והוא אובייקט JS.

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

במאמר הבא אנו נדבר מעט על מודולי הליבה של Node.js – ואפילו נבנה, כמו כל המדריכים, שרת http משלנו!

⚠️ תזכורת – המדריכים האלו הם רק טעימה, בספר שלי "ללמוד Node.js בעברית" יש הסברים מלאים ומקיפים על השפה המיועדים ללימוד עצמי. עם תרגילים והסברים. הספר יצא לאור בשיתוף הקריה האקדמית אונו ובתמיכת החברות אלמנטור, ו-Iron source ונערך טכנית על ידי בנג'י גרינבאום (מפתח ליבה של Node.js), גיל פינק ומתכנתים מעולים נוספים. 

פוסטים נוספים שכדאי לקרוא

פתרונות ומאמרים על פיתוח אינטרנט

נגישות טכנית – פודקאסט ומבוא

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

גלילה לראש העמוד