
استفاده از Eslint با توجه به اینکه جاوااسکریپت کلا خیلی بی در پیکر هست یه جورایی استفاده ازش اجباریه.
از اونجایی که میدونید جاوااسکریپت خیلی ساختار خاصی نداره و کلا با همه چی اوکی هست 😅
دلیلش هم چیزی که من متوجه شدم خلاصش این هست که به خطا نخوره.
مثلا فرض کنید خواستید یه عدد رو با یه رشته جمع کنید؛ اگه قرار بود جاوااسکریپت همون
خط اول خطا بده، کل سایت بالا نمیومد 😁
بعد از این موارد بود که TypeScript و ابزارهایی مثل ESLint اومدن و کمک کردن کدهای تمیزتر، با خطای کم تر و قابلپیشبینیتر بشه.

تو این پست قصد ندارم در مورد نصب و این موارد صحبت کنم چون به صورت پیش فرض معمولا موقع نصب react و یا next ، پکیج های مرتبط به lint هم نصب میشه.
این دو Rule جزو مهمترین مواردی هستن که جلوی خیلی از باگهای ریز و درشت، مخصوصاً در کار با رشتهها و تبدیل نوعها رو میگیرن.
no-implicit-coercion اجازه نمیده که با عملیات عجیبوغریب، نوع دادهها رو بهصورت غیرمستقیم عوض کنیم.prefer-template هم ما رو مجبور میکنه بهجای استفاده از + برای ساخت رشته، از Template Literal استفاده کنیم.
// ❌ استفاده از + برای ترکیب رشتهها const firstName = "mahdi"; const lastName = "falahati"; const fullName = firstName + " " + lastName; // هر دو رشته هستند const greeting = "سلام " + firstName; // هر دو رشته هستند // ✅ روش بهتر: const fullName = `${firstName} ${lastName}`; const greeting = `سلام ${firstName}`; // ❌تبدیل به رشته const age = 25; const ageString = age + ""; // ❌ تبدیل عدد به رشته const ageString = "" + age; // ❌ تبدیل عدد به رشته // ✅ تبدیل صریح const ageString = String(age); // ✅ واضح و خوانا const ageString = age.toString(); // ✅ یا این روش // ❌ ترکیب عدد و رشته const userId = 123; const message = "User ID: " + userId + ""; // "" اضافی و بیمعنی // ✅ const userId = 123; const message2 = `User ID: ${userId}`; // روش بهتر
'no-implicit-coercion': ['error', { boolean: true, // Disallow !!value number: true, // Disallow +value or value * 1 string: true, // Disallow value + "" disallowTemplateShorthand: false // Allow ${value} for string coercion }], "prefer-template": "error"
یکی از بهترین مزیت های استفاده از eslint یکدست شدن کدهای افراد تیم هست.
حداقل مزیتی که داره تفاوت کمتری بین کد افراد تیم پیش میاد و Code Review راحت تر میکنه.
همچنین Diff فایلها توی گیت خیلی تمیزتر و قابلفهمتر میشه.

"rules": { "object-curly-spacing": ["error", "always"], "key-spacing": ["error", { "afterColon": true }], "keyword-spacing": ["error", { "before": true, "after": true }] }
این موارد باعث میشه فاصله بین کلید و مقدار در آبجکتها، فاصله بین Keyهای آبجکت و فاصله قبل و بعد از کلمات کلیدی مثل if, else, try. با یک فرمت خاص فقط قابل قبول باشه و در غیر این صورت خطا میده.
"rules": { "max-len": ["error", { "code": 100, "ignoreUrls": true, "ignoreStrings": true, "ignoreTemplateLiterals": true, "ignoreRegExpLiterals": true }] }
با استفاده از این rule میتونیم تعداد کاراکترهای مجاز در هر خط محدود کنیم.
البته بعضی مواقع این مورد مشکل ساز میشه برای مثال import بعضی از پکیج ها امکان داره از تعداد خط مشخص شده بیشتر بشه.
برای حل این مشکل، میتونیم مثل کانفیگ بالا از گزینههای ignore... استفاده کنیم تا به رشتههای طولانی یا لینکها کاری نداشته باشه. یا در موارد خیلی خاص، بالای اون خط از کامنت // eslint-disable-line استفاده کنیم.
در بخش قبلی در مورد چند rule برای یکدست شدن کدها صحبت کردیم، در این قسمت چندتا rule مهم برای تمیزتر شدن کدها و همچنین باگ کمتری پیش بیاد.

// ❌ باگهای عجیب ناشی از استفاده از == if (0 == false) { console.log("چرا اجرا شدی؟!"); } if ("1" == 1) { // اینم اجرا میشه چون رشته "1" تبدیل به عدد میشه 😐 } // ✅ روش درست با === if (0 === false) { // اجرا نمیشه، چون عدد 0 با بولین false یکی نیست }
== معمولاً بهخاطر تغییر خودکار نوعها نتیجههای عجیب میده، برای همین حتما باید از === استفاده بشه.
TypeScript هم تا حد زیادی جلوی این اشتباهها رو میگیره، ولی اساسا جلوی اینکه == استفاده کنیم نمیگیره یه مثال که تایپ اسکریپت جلوش نمیگیره.
const value = 'test' as unknown as number; if (value == 5) {}
اینجا TS فکر میکنه value یه عدد هست، ولی در زمان اجرا همچنان یه رشتهست و == میتونه رفتار غیرمنتظره ایجاد کنه.
هرچند احتمال داشتن چنین cast هایی کم بهنظر میرسه، ولی خب… در جاوااسکریپت هیچچیزی بعید نیست 😅
به نظرم rule مهمی هست خیلی وقت ها احتمالش وجود داره که یک console log گذاشته باشیم و فراموش شده باشه پاکش کنیم چهبسا که یک سری اطلاعات مهم هم داخلش باشه 🥲
"no-console": ["error", { "allow": ["warn", "error"] }]
البته بعضی موارد پیش میاد که نیاز هست یک console warn یا error استفاده کنیم با این روش میتونیم اجازه استفاده بدیم.
خیلی وقتها پیش میاد یک متغیر یا یک تابع تعریف کنیم اما فراموش کنیم ازش استفاده کنیم، یا موقع Refactor کردن دیگه لازمش نداریم و همونطور توی کد بمونه.
برای همین Eslint با این Rule جلوش رو میگیره:
"no-unused-vars": ["error", { "vars": "all", "args": "none", "ignoreRestSiblings": true }]
به این شکل:
هر متغیر، تابع یا importی که استفاده نشه → خطا ❌
روی آرگومانهای تابع سختگیر نیست (برای جلوگیری از خطاهای الکی)
در destructuring هم باعث مزاحمت نمیشه
args: "none"// مثال رایج در map items.map((item, index) => { return item.name; //index is not used, but with args: "none" it's not a problem });
ignoreRestSiblings: trueوقتی از Rest استفاده میکنیم تا بقیه پراپرتیها رو جدا کنیم، اما اون متغیرهای اولیه (Siblingها) رو لازم نداریم و بلااستفاده میمونن.» (چون در واقع ما از Rest استفاده میکنیم، ولی از اون متغیرهایی که جدا کردیم مثل password استفاده نمیکنیم).
بدون این تنظیم خطا میداد، با این تنظیم خطا نمیده.
const user = { name: "mahdi", age: 25, password: "12345" }; const { password, ...safeUser } = user; console.log(safeUser);
این کار کمک میکنه کد تمیزتر، قابلخواندنتر و بدون بخشهای مرده باشه.
در نهایت، بد نیست بدونیم استفاده از ESLint همیشه هم بدون دردسر نیست.
گاهی یه خط ساده مینویسی و پنجتا خطا تحویل میگیری، یا سر یه Rule خاص کلاً کُپ میکنی که چرا الان گیر داده 😅
بعضی وقتها هم مثل عکس پایین، کار به جایی میرسه که به این فکر میفتی که ولش کن اصلا نخواستیم کلا غیرفعالش میکنیم میره 😁
"wtf is wrong with eslint?!" 😂
اما واقعیت اینه که همین سختگیریهاست که باعث میشه کد تمیزتر، و قابلنگهداریتری داشته باشیم.
امیدوارم این متن براتون مفید بوده باشه ❤️
اگر نظری داشتید یا تجربهای با ESLint دارید و یا چیزی اشتباه گفتم ممنون میشم بهم تو نظرات بگید 🙏
