بهترین رویه های Node.js با بهره گیری از قابلیت های مدرن – راهنمای کاربردی


Node.js یک محیط زمان اجرای محبوب برای نوشتن اپلیکیشنها محسوب میشود. این اپلیکیشنها اغلب دارای کیفیت بالایی برای محیط پروداکشن هستند و از سوی افراد زیادی مورد استفاده قرار میگیرند. برای این که نگهداری این اپلیکیشنها آسانتر باشد، در این مقاله برخی نکات و ترفندها را به صورت قابلیتهای مدرن این محیط زمان اجرا مطرح میکنیم که به عنوان بهترین رویه های Node.js به تولید کد تمیز و با قابلیت نگهداری بالا کمک میکند.
Const را به let ترجیح بدهید و var را دور بیندازید
Var یک کلیدواژه منسوخ برای ایجاد متغیرها است که هرگز دیگر استفاده نخواهد شد. برخلاف const و let دامنه آن ناسازگار است. var دارای دامنه تابعی است، از این رو میتواند از خارج از بلوکها نیز مورد دسترس قرار گیرد و بدین جهت تولید مشکل در کد کند. Let و const دارای دامنه بلوکی هستند و نمیتوانند خارج از بلوکی که در آن تعریف شدهاند مورد دسترسی قرار گیرند. Const از انتساب مجدد مقدار دیگری به ثابت جلوگیری میکند.
برای نمونه اگر کد زیر را داشته باشیم:
1var callbacks = [];
2(function() {
3 for (var i = 0; i < 5; i++) {
4 callbacks.push( function() { return i; } );
5 }
6})();
7console.log(callbacks.map( function(cb) { return cb(); } ));
خروجی مانند زیر تولید میکند:
[5, 5, 5, 5, 5]
دلیل این امر آن است که مقدار i تا زمانی که مقدار آن به 5 نرسد به callback ارسال نمیشود. در این صورت هر یک از آنها را با مقدار 5 اجرا میکنیم. کد فوق در عمل به صورت زیر است:
1var callbacks = [];
2(function() {
3 var i
4 for (i = 0; i < 5; i++) {
5 callbacks.push( function() { return i; } );
6 }
7})();
8console.log(callbacks.map( function(cb) { return cb(); } ));
و این ناشی از خصوصیت hoisting است. به این ترتیب مقدار i باید در زمان اجرای callback برابر با 5 باشد. متغیرهای let اجازه host شدن را نمیدهند، از این رو با این مشکل مواجه نمیشویم. بنابراین دیگر با این مشکل مواجه نخواهیم شد:
1var callbacks = [];
2(function() {
3 for (let i = 0; i < 5; i++) {
4 callbacks.push( function() { return i; } );
5 }
6})();
7console.log(callbacks.map( function(cb) { return cb(); } ));
چنان که میبینید var دردسرساز است و موجب سردرگمی میشود، از این رو هرگز نباید از آن استفاده کنید.
ماژولها را در ابتدای کد و نه داخل تابعها require کنید
نکته مهم دیگری که باید توجه داشته باشیم، این است که ماژولها باید در ابتدای هر فایل هر کد require شوند. به این ترتیب میتوانیم به سرعت متوجه شویم که چه وابستگیهایی مورد نیاز هستند.
Require به صورت همگام (synchronous) در Node.js عمل میکند. از این رو در صورتی که درون تابع فراخوانی شوند، ممکن است بخشهای دیگر کد را در زمانهای بحرانیتری از اجرا شدن بازدارند. اگر هر نوع ماژول یا وابستگی require شده خطایی صادر کند و سرور کرش کند، بهتر است این موضوع سریعتر مشخص شود.
ماژولها را با پوشه و نه فایل require کنید
ماژولها در Node.js باید به وسیله پوشههایشان و نه مستقیماً از طریق فایلها require شوند. دلیل این امر آن است که نمیخواهیم در صورت تغییر یافتن ساختار پوشه ماژول، عبارت require در اپلیکیشنهای کاربر از کار بیفتد. از این رو کد زیر خوب است:
require('./foo');
و کد زیر بد محسوب میشود:
require('./bar/foo');
از عملگر === استفاده کنید
عملگر برابری صریح (===) بهتر از عملگر == است، زیرا پیش از مقایسه متغیرها، نوع آنها را تبدیل نمیکند. با استفاده از عملگر ===، هر دو عملوند باید نوع یکسانی داشته باشند تا برابر ارزیابی شوند.
این وضعیت خوبی است، زیرا از بروز خطاهای زیادی در زمان مقایسه مقادیر جلوگیری میکند. در مقابل استفاده از عملگر == بد است زیرا همه مقایسههای زیر مقدار true بازگشت میدهند:
1null == undefined
2false == '0'
30 == ''
40 == '0'
در اغلب موارد این چیزی نیست که ما میخواهیم. همچنین موارد حاد بسیار زیاد دیگری نیز وجود دارند که در صورت استفاده از عملگر == موجب بروز خطا در اپلیکیشن میشوند. بنابراین باید همواره از عملگر === استفاده کنیم.
از Async Await و Avoid Callbacks استفاده کنید
از زمان Node 8 LTS به بعد async و await به قابلیتهای Node اضافه شدهاند. از این رو باید در همه موارد ممکن از آن برای زنجیرهسازی promise-ها استفاده کنیم. این دستور یک میانبر خوب برای زنجیرهسازی promise-ها محسوب میشود.
API های callback قدیمی در ماژولهای اصلی Node مانند fs به تدریج به API مربوط به promise تبدیل میشوند. بنابراین میتوانیم از async و await در جاهایی به غیر از کد خودمان نیز استفاده کنیم. برای مدیریت خطاها در async و await میتوانیم به صورت زیر عمل کنیم:
1(async ()=>{
2 try {
3 await Promise.reject('error')
4 }
5 catch(ex){
6 console.log(ex);
7 }
8})();
در کد فوق، خطا را در بلوک catch به دام میاندازیم و مقدار ex را لاگ میکنیم که باید 'error' از Promise.reject باشد.
سخن پایانی
سازههای جدید در جاوا اسکریپت به جهت مفید بودن معرفی میشوند. این قابلیتهای جدید موجب کوتاهتر و تمیزتر شدن کد میشوند. این قابلیتها موجب سهولت کدنویسی و افزایش خوانایی و آسانی تغییر میشوند. به این ترتیب هر کس از کدنویسی در جاوا اسکریپت لذت میبرد. سازههای قدیمی مانند var باید به طور کامل از کد حذف شوند.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- آموزش ساخت اپلیکیشن چت با رمزنگاری سراسری
- مجموعه آموزشهای برنامهنویسی
- Node.js چیست؟ — به زبان ساده
- آموزش Node.js — مجموعه مقالات مجله فرادرس
==