Node.js چیست؟ — به زبان ساده
Node.js یک محیط «زمان اجرا» (Runtime) برای زبان برنامهنویسی جاوا اسکریپت است. در این نوشته به توضیح این مفهوم و روش کار آن میپردازیم. محیط زمان اجرای Node.js شامل هر موردی است که برای اجرای برنامههای نوشته شده به زبان جاوا اسکریپت لازم است.
Node.js زمانی متولد شد که توسعهدهندگان اصلی جاوا اسکریپت آن را از چیزی که میتوانست روی مرورگر اجرا شود، به حالتی بسط دادند که بتواند به صورت یک اپلیکیشن مستقل روی رایانه اجرا شود. اینک ما میتوانیم کارهای بسیار بیشتری با جاوا اسکریپت انجام دهیم و هدفمان صرفاً ایجاد تعاملپذیری در وبسایتها نیست.
جاوا اسکریپت در حال حاضر ظرفیت انجام کارهایی را یافته است که زبانهای اسکریپتنویسی دیگر مانند پایتون نیز میتوانند انجام دهند. هم جاوا اسکریپت مرورگر و هم Node.js روی موتور زمان اجرای V8 اجرا میشوند. این موتور کد جاوا اسکریپت را گرفته و آن را به کد سریع برای ماشین تبدیل میکند. کد ماشین کد سطح پایینی است که رایانه میتواند بدون نیاز به تفسیر کردن اجرا کند.
چرا باید از Node.js استفاده کرد؟
تعریف رسمی ارائه شده از سوی وبسایت Node.js چنین است:
Node.js یک محیط زمان اجرای جاوا اسکریپت است که بر مبنای موتور جاوا اسکریپت V8 کروم ساخته شده است.
Node.js از مدل رویداد-محور و غیر مسدودکننده I/O بهره میگیرد که آن را سبک و کارآمد ساخته است. اکوسیستم بسته Node.js یعنی npm بزرگترین اکوسیستم کتابخانههای متن-باز در دنیا محسوب میشود.
توضیح دادیم که Node.js یک محیط زمان اجرای جاوا اسکریپت است. در ادامه به بررسی بخشهای دیگر تعریف فوق میپردازیم تا دلیل محبوبیت روزافزون آن را بهتر درک کنیم.
منظور از I/O در تعریف رسمی Node.js همان «ورودی/خروجی» (Input/Output) است. این ورودی/خروجی میتواند هر چیزی از خواندن/نوشتن فایلهای محلی تا ایجاد یک درخواست HTTP به یک API باشد. عملیات I/O زمانبر است و از این رو موجب مسدود شدن کارکردهای دیگر میشود.
برای نمونه تصور کنید ما از یک پایگاه داده در بکاند درخواست میکنیم که جزییات کاربر user1 و user2 را ارسال کند و سپس آنها را روی صفحه یا کنسول نمایش میدهیم. پاسخ دادن به این درخواست ما زمانی طول میکشد؛ اما هر دو درخواست دادههای کاربر میتوانند به صورت مستقل از هم و به طور همزمان اجرا شوند.
مسدودسازی I/O
در روش مسدودسازی، درخواست دادههای user2 تا زمانی که دادههای user1 روی صفحه نمایش نیافته است ارسال نخواهد شد.
اگر این یک سرور وبسایت باشد، باید یک نخ تازه برای هر کاربر جدید آغاز کنیم. اما جاوا اسکریپت «تکنخی» (single-threaded) است. البته مفهوم تکنخی جزو ماهیت بنیادی جاوا اسکریپت نیست؛ اما حلقه رویداد آن تکنخی است. این موضوع را در ادامه بیشتر بررسی میکنیم. از این رو جاوا اسکریپت برای اجرای وظایف «چندنخی» (multi-threaded) چندان مناسب نیست.
عدم مسدودسازی I/O
از سوی دیگر، با استفاده از یک درخواست غیر مسدودکننده میتوانیم بدون نیاز به منتظر شدن برای دریافت دادههای کاربر user1، یک درخواست داده برای user2 ارسال کنیم. در واقع هر دو درخواست به صورت موازی آغاز میشوند.
این رویکرد عدم مسدودسازی I/O نیاز به چندنخی را حذف میکند، زیرا سرور میتواند چندین درخواست را به صورت همزمان مدیریت کند. در ادامه به توضیح گام به گام مختصری در مورد طرز کار حلقه رویداد جاوا اسکریپت میپردازیم.
- ()main به «پشته فراخوانی» (Call Stack) «پوش» (push) میشود.
- ()console.log به پشته فراخوانی push میشود و سپس شروع به اجرا کرده و pop میشود.
- (setTimeout(2000 به پشته push میشود. (setTimeout(2000 یک API برای Node است. زمانی که آن را فراخوانی میکنیم یک جفت رویداد-callback ثبت میکنیم. رویداد به مدت 2000 میلیثانیه منتظر میماند و سپس تابع callback اجرا میشود.
- پس از ثبت کردن آن در API–ها، (setTimeout(2000 از پشته فراخوانی pop میشود.
- اینک (setTimeout(0 به ترتیبی ثبت میشود. در این زمان دو API برای Node داریم که منتظر اجرا هستند.
- پس از این که به مدت 0 ثانیه منتظر ماندیم، (setTimeout(0 به صف callback منتقل میشود و همان اتفاقی که برای (setTimeout(2000 افتاد تکرار میشود.
- در صف callback، تابعها منتظر میمانند تا پشته فراخوانی خالی شود؛ چون هر زمان تنها یک گزاره میتواند اجرا شود. اجرای این کار بر عهده حلقه رویداد است.
- دستور آخر ()console.log اجرا میشود و ()main از پشته فراخوانی pop میشود.
- حلقه رویداد میبیند که پشته فراخوانی خالی شده است و صف callback خالی نیست. بنابراین (با ترتیب FIFO) این callback-ها برای اجرا به پشته فراخوانی منتقل میشوند.
NPM
کتابخانههایی وجود دارند که از سوی جامعه بزرگی از توسعهدهندگان تولید شدهاند. این جامعه به حل اغلب مسائل عمومی پرداخته است. npm که اختصاری برای «نرمافزار مدیریت بسته Node» یعنی (Node Package Manager) است بستههایی دارد که میتوان در اپلیکیشنها مورد استفاده قرار داد و بدین ترتیب فرایند توسعه اپلیکیشن را سریعتر و کارآمدتر ساخت.
Require
Require سه کار را انجام میدهد:
- ماژولهایی مانند سیستم فایل و HTML را که با Node.js بستهبندی شدهاند از API مربوط به Node.js بارگذاری میکند.
- کتابخانههای شخص ثالث مانند Express و Mongoose را که از npm نصب میشوند بارگذاری میکند.
- امکان require کردن فایلهای خودتان را فراهم میسازد و بدین ترتیب امکان ماژولهسازی پروژه را ایجاد میکند.
Require یک تابع است و پارامتری به نام path میپذیرد و مقدار module.exports را بازگشت میدهد.
ماژولهای Node
یک ماژول Node به بلوک با قابلیت استفاده مجدد گفته میشود که وجود آن به صورت تصادفی روی کدهای دیگر تأثیر نمیگذارد. هرکسی میتواند ماژولهای خاص خود را بنویسد و در اپلیکیشنهای مختلف مورد استفاده قرار دهد. Node.js مجموعهای از ماژولهای داخلی دارد که میتوان بدون نیاز به نصب چیز دیگری مورد استفاده قرار داد.
V8 با بهرهگیری از ++C موجب ارتقای جاوا اسکریپت شده است
V8 یک محیط زمان اجرای اوپنسورس است که در ++C نوشته شده است. فرایند کار به صورت زیر است:
JavaScript -> V8(C++) -> Machine Code
V8 اسکریپتی به نام ECMAScript را پیادهسازی کرده است. ECMAScript از سوی بنیاد بینالمللی Ecma برای استانداردسازی جاوا اسکریپت ایجاد شده است.
V8 میتواند به صورت مستقل اجرا شود و یا در یک اپلیکیشن ++C جاسازی شود. V8 دارای قلابهایی است که امکان نوشتن کد ++C را به ما میدهد که میتواند متعاقباً در اختیار جاوا اسکریپت قرار گیرد.
این وضعیت اساساً به ما امکان میدهد که با جاسازی V8 در کد ++C ویژگیهایی به جاوا اسکریپت اضافه کنیم به طوری که کد ++C قابلیت درک بیشتری از آن چه ECMAScript تعیین کرده است داشته باشد.
دقت کنید که به جز V8 که از سوی کروم عرضه شده موتورهای زمان اجرای زیادی برای جاوا اسکریپت وجود دارند که شامل SpiderMonkey از سوی فایرفاکس، Chakra از سوی مایکروسافت و غیره میشود.
رویدادها
رویداد چیزی است که در اپلیکیشن رخ میدهد و میتوان به آن پاسخ داد. دو نوع رویداد در Node.js وجود دارند.
- رویدادهای سیستمی: که از هسته ++C از یک کتابخانه به نام libuv ناشی میشوند، مانند اعلام پایان یافتن دانلود یک فایل.
- رویدادهای سفارشی: هسته جاوا اسکریپت.
نوشتن برنامه Hello World در Node.js
بالاخره هیچ راهنمایی در مورد یک زبان برنامهنویسی بدون معرفی روش نوشتن Hello World کامل محسوب نمیشود. یک فایل به نام app.js ایجاد کنید و کد زیر را در آن قرار دهید:
1console.log("Hello World!");
ترمینال Node خود را باز کنید، دایرکتوری خود را به پوشهای که فایل در آن ذخیره شده تغییر دهید و دستور زیر را اجرا کنید:
node app.js
بدین ترتیب موفق شدهایم نخستین برنامه خود را در Node.js بنویسیم.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزش های برنامه نویسی
- Node.js چیست و چه نقشی در توسعه وب دارد؟ — به زبان ساده
- مجموعه آموزش های مهندسی نرم افزار
- آموزش جاوا اسکریپت (JavaScript)
- Node.js و ابزارها و تکنیکها برای ساخت سرورهای قدرتمند و سریع
- آموزش راه اندازی و اجرای Express ،Node.js و MongoDB — راهنمای گام به گام
==
سلام استاد
بنده درباره یک مسئله ای نزدیک به یک هفته تحقیق کرم ولی به نتیجه ای نرسیدم. ممنون میشم اگه کمکم کنید:
1- من میخوام یک سایت شبیه وبسایت آپارات ( وبسایت اشتراک ویدئو و استریم زنده ) طراحی کنم. با توجه به میزان بازدید بالا – حجم ویدئو ها و غیره: به نظر شما از node.js استفاده کنم یا php ؟ برای همچین سایتی درحال حاظر از چه زبانی استفاده کنم؟
2- حالا اگه باز بخوام یه سیستم چت سطح متوسط هم به سایت اضافه کنم چطور؟ حالا از چه زبانی استفاده کنم؟
3- یک وبسایت در سروری با رم 4 گیگابایتی و پردازنده 2 هسته ؛ با php و node.js هر کدوم چندتا کاربر میتونن همزمان در سایت کانکشن برقرار کنن و یا آنلاین باشن؟
4- نظر شما به طور کلی در این باره چیه؟
با تشکر ار شما استاد.