Kevin Dongaoor در سال 2009 ، CommonJS را با هدف ایجاد یک اکوسیستم در ماژول های جاوا اسکریپت در سرور ساخت . Node.js نیز ویژگی های CommonJS را دنبال کرد .
بخش 8 – آموزش Node.JS ، سیستم ماژول برمبنای فایل
Kevin Dongaoor در سال 2009 ، CommonJS را با هدف ایجاد یک اکوسیستم در ماژول های جاوا اسکریپت در سرور ساخت . Node.js نیز ویژگی های CommonJS را دنبال کرد . در زیر بخشی از این ویژگی های چشمگیر را در مورد سیستم ماژول ملاحظه می نمایید :
· هر فایل ، ماژول خود می باشد .
· هر فایل به ماژول جاری تعریف شده توسط متغیر module دسترسی خواهد داشت .
· Export ماژول جاری با استفاده از متغیر module.exports تعریف می گردد .
· برای import کردن ماژول از تابع سراسری require استفاده می گردد .
یک مثال روشن برای به اشتراک گذاری یک فایل js مانند foo.js با بخش های مختلف نرم افزار بصورت زیر می باشد . که با استفاده از module.exports این کار صورت گرفته است .
بر اساس این تابع از یک فایل ( بعنوان مثال ) با عنوان bar.js ، براحتی می توانیم foo را import نماییم .
Node.js طراحی شده تا ساده باشد ! و این را می توان از سیستم ماژول آن فهمید . در Node.js سه نوع ماژول وجود دارد . modules , file modules , node_modules که تمامی این سه نوع ماژول از تابع require استفاده می کنند . که ما در حال حاضر در مورد file modules ها بحث می کنیم .
زمانی که ما تابع require را با استفاده از یک مسیر نسبی ( بطور مثال require(‘.filename’) و یا require(‘../foldername/filename’) ) فراخوانی می کنیم ، Node.js فایل جاوا اسکریپت مقصد را در یک حوزه و محدوده ی جدید اجرا نموده و نتیجه ی نهایی را برای module.exports در آن فایل برمیگرداند .
Node.js امن می باشد
ماژول در بسیاری از محیط های برنامه نویسی امن نمی باشند و محدوده ی عمومی را آلوده و نا امن می کنند . یکی از این مثال ها PHP است . تکه کد زیر را در نظر بگیرید :
اگر شما نیاز به استفاده ی مجدد از این تابع در فایل دیگری ( بطور مثال bar.php ) داشتید می توانید از تابع include استفاده نمایید . و تمامی موارد موجود در foo.php بخشی از محدوده ی سراسری bar.php خواهد شد .
این طراحی یک مفهوم منفی خواهد داشت . شما هر آنچه در foo دارید را در فایل جاری می توانید تغییر دهید . و در این حالت شما نمی توانید دو فایل با نام های foo1 و foo2 را بسازید . چرا که ممکن است دو متغیر با نام های یکسان داشته باشند . شما در php این مشکل را با استفاده از namespace ها حل خواهید کرد . اما Node.js از اینکار پرهیز می کند .
استفاده از تابع require تنها به شما متغیرهای module.exports را خواهد داد . و شما نیاز دارید تا نتیجه را به یک متغیر محلی در آن حوزه نسبت دهید .
در اینجا ما برخورد حوزه ها را نداشته و برای هر متغیر محلی نام ها و فایل های مجزا را خواهیم داشت که در کنار یکدیگر بدون مشکل ادامه خواهند داد .
بارگزاری ماژول بصورت مشروط
رفتار require مانند توابع دیگر در جاوا اسکریپت می باشد . تنظیمات خاصی ندارد . و در واقع شما می توانید برای فراخوانی آن شرطی تعیین نمایید و این بدان معناست که شما می توانید ماژول مورد نظر خود را تنها در صورت نیاز فراخوانی کنید .
Blocking
تابع require اجرای ادامه ی کدها را متوقف می کند تا اینکه بارگزاری ماژول کامل گردد . و در واقع به شما اجازه می دهد تا از callback ها غیرضروری که برای I/O های غیرهمزمان نیاز دارید پرهیز کنید .
Cached
همانگونه که می دانید خواندن چیزی از سیستم فایل کندتر از خواندن آن از RAM می باشد . بنابراین اگر یک بار فراخوانی require بخشی از فایل را خواند module.exports ذخیره ( cached ) خواهدشد . و در فراخوانی های بعدی آن ماژول از داخل RAM خوانده شده و سرعت دستیابی سریع تر خواهد بود .
در کد بالا با اجرای آن در مرحله ی اول زمانی بیشتر از صفر خواهیم داشت اما در بار دوم دستیابی زمانی تقریبن برابر با صفر را تجربه خواهیم کرد و این بهمان دلیل cache شدن می باشد .
Shared State
داشتن مکانیسمی برای به اشتراک گذاری وضعیت ماژول ها در بخش های مختلف مفید می باشد . از آنجایی که ماژول ها cache می شوند هر ماژولی که بطور مثال به foo.js نیاز داشته باشد باید یک نسخه ی یکسان از شیء foo را از ماژول foo.js بگیرد .
Object Factories
همانطور که مشاهده کردید در هر بار فراخوانی require شیء یکسانی از همان فایل برگشت داده خواهد شد . اگر شما بخواهید یک شیء جدید در هر بار فراخوانی داشته باشید باید از مکانیسم فراخوانی توابع برای require استفاده نمایید . شما می توانید یک خروجی تابع از ماژول منبع خود گرفته و آن را بعنوان شیء جدید بازگشت دهید . یک مثال از این کاربرد را در زیر مشاهده می نمایید :
شاد و سلامت باشید
محمد جعفری فوتمی