يمكن لمطوري Node.js تقريبًا أن يخبركوا ماذا تتطلب () "وظيفة" ، ولكن كم منا يعرف حقًا كيف يعمل؟ نستخدمه كل يوم لتحميل المكتبات والوحدات النمطية ، ولكن سلوكها هو لغز بالنسبة لنا.
بدافع الفضول ، قمت بالتعرف على الكود الأساسي للعقدة لمعرفة ما حدث تحت المحرك. ولكن هذه ليست وظيفة واحدة. لقد وجدت module.js في نظام وحدة العقدة. يحتوي الملف على وحدة أساسية قوية بشكل مدهش وغير مألوف نسبيًا تتحكم في تحميل كل ملف وتجميعه وتخزينه للتخزين المؤقت. `` ``) `، ظهوره هو مجرد غيض من الجبل الجليدي.
الوحدة النمطية
نسخة الكود كما يلي:
وحدة الوظائف (المعرف ، الأصل) {
this.id = id ؛
this.exports = {} ؛
this.parent = الوالدين ؛
// ...
في module.js ، يلعب بشكل أساسي دورين داخل Node.js. أولاً ، يوفر أساسًا لجميع وحدات Node.js. كل ملف هو مثيل جديد للوحدة الأساسية جديدة ، ولا يزال موجودًا حتى بعد تشغيل الملف. هذا هو السبب في أننا قادرون على إرفاق الخصائص إلى Module.exports وإعادتها عند الحاجة.
المهمة الرئيسية الثانية لهذه الوحدة هي التعامل مع آلية تحميل الوحدة النمطية للعقدة. تعد العملية المستقلة لوظيفة "المتطلبات" التي نستخدمها في الواقع وحدة مفهوم مجردة. REQUIRE ، والتي هي بحد ذاتها مجرد تغليف بسيط حول وظيفة module._load. تعالج طريقة التحميل هذه التحميل الفعلي لكل ملف وتبدأ رحلتنا هناك.
الوحدة النمطية
نسخة الكود كما يلي:
module._load = function (request ، parent ، ismain) {
// 1. تحقق من الوحدة النمطية.
// 2. قم بإنشاء مثيل وحدة جديدة إذا كان ذاكرة التخزين المؤقت فارغة.
// 3. احفظه إلى ذاكرة التخزين المؤقت.
// 4. call module.load () مع اسم الملف الخاص بك.
// سيؤدي هذا إلى استدعاء module.compile () بعد قراءة محتويات الملف.
// 5. إذا كان هناك خطأ في تحميل/تحليل الملف ،
// حذف الوحدة السيئة من ذاكرة التخزين المؤقت
// 6. وحدة الإرجاع
} ؛
MODULE._LOAD مسؤولة عن تحميل وحدات جديدة وإدارة ذاكرة التخزين المؤقت للوحدة. يقوم تحميل ذاكرة التخزين المؤقت التي تم تحميلها بكل وحدة يقلل من عدد قراءات الملفات الزائدة ويمكن أن تسرع تطبيقك بشكل كبير. بالإضافة إلى ذلك ، يتيح مثيل الوحدة المشتركة للوحدات النمطية ذات خصائص Singleton البقاء في الحالة في المشروع.
إذا لم تكن هناك وحدة نمطية في ذاكرة التخزين المؤقت ، فسيقوم module._load بإنشاء وحدة قاعدة جديدة للملف. سيخبر الوحدة النمطية بقراءة محتويات الملف الجديد قبل إرسالها إلى Module._compile. [1]
إذا لاحظت الخطوة رقم 6 أعلاه ، فسترى أن الوحدة النمطية. تم إرجاع Exports إلى المستخدم. هذا هو السبب عند تحديد استخدام الواجهة العامة ، يمكنك استخدام الصادرات و module.esports ، لأن module._load ستعيد محتويات المتطلبات بعد ذلك. لقد فوجئت بعدم وجود ميزات أخرى هنا ، ولكن سيكون من الأفضل لو كان هناك.
الوحدة النمطية
نسخة الكود كما يلي:
module.prototype._compile = function (المحتوى ، اسم الملف) {
// 1. إنشاء المستقلة يتطلب وظيفة التي تستدعي module.require.
// 2. إرفاق طرق المساعد الأخرى لتتطلب.
// 3. يلف رمز JS في وظيفة توفر متطلباتنا ،
// الوحدة النمطية ، إلخ. المتغيرات محليا إلى نطاق الوحدة النمطية.
// 4. قم بتشغيل هذه الوظيفة
} ؛
・ هذا هو المكان الذي تحدث فيه المعجزة الحقيقية. أولاً ، يتم إنشاء وظيفة متطلبات تشغيلية خاصة ومستقلة للوحدة النمطية. هذه ميزة نحتاجها وكلها على دراية بها. الوظيفة نفسها ليست سوى تغليف في الوحدة النمطية.
・ طلب (): تحميل وحدة خارجية
・ requist.Resolve (): تحليل اسم الوحدة إلى مسارها المطلق
・ المتطلبات. main: الوحدة الرئيسية
・ requist.cache: جميع الوحدات المخبأة
・ ・ required.Extensions: طريقة تجميع يمكن استخدامها لكل نوع ملف صالح وفقًا لتمديده
بمجرد أن تكون المتطلبات جاهزة ، سيتم تغليف رمز المصدر المحمّل بالكامل في وظيفة جديدة ، مما يسمح لها بقبول المتطلبات والوحدة والنمط والتصدير وجميع المتغيرات المكشوفة الأخرى كمعلمات. هذه وظيفة تم إنشاؤها فقط لتغليف الوحدات النمطية لمنع التعارض مع بيئة Node.js.
نسخة الكود كما يلي:
(الوظيفة (الصادرات ، المتطلبات ، الوحدة النمطية ، __filename ، __dirname) {
// تم حقن الكود الخاص بك هنا!
}) ؛
يتم تنفيذ طريقة module._compile بشكل متزامن ، لذلك يمكن للمكالمة إلى الوحدة النمطية. _ تحميل فقط الانتظار حتى يتم تشغيل الرمز وإرجاع module.exprts إلى المستخدم.
ختاماً
لذلك ، لقد فهمنا بالفعل رمز المتطلبات الكامل ولدينا فهم أولي لكيفية عمله.
إذا قمت بذلك على طول الطريق ، فأنت مستعد للسر الأخير: طلب ("الوحدة النمطية"). هذا صحيح ، يمكن تحميل نظام الوحدة النمطية نفسه من خلال نظام الوحدة النمطية. بداية. قد يبدو هذا غريباً ، لكنه يسمح للمساحة للمستخدم بالتفاعل مع أنظمة تحميل الوحدة النمطية دون الخوض في Node.js Core. الوحدات النمطية الشعبية كلها مبنية مثل هذا. [2]
إذا كنت تريد معرفة المزيد ، فيرجى التحقق من رمز المصدر Module.js بنفسك. لا يزال هناك العديد من الأشياء التي ستكون كافية لك أن تعاني من صداع لفترة من الوقت. يمكن للمرء أن يخبرني ما هي node_module_contexts "ولماذا تمت إضافتها يمكن أن تحصل على نقاط مكافأة :)
[1] يتم استخدام طريقة module._compile فقط لتشغيل ملفات JavaScript. يجب تحليل ملف JSON من خلال json.parse () وإرجاعه
[2] ومع ذلك ، فإن كلتا الوحدات مبنية على طرق الوحدة الخاصة مثل الوحدة النمطية. يمكنك أن تعتقد أن هذا ليس أفضل بكثير ...