کانفیگ کامل ESLint برای React و Next JS

مطالب پراکنده و ناقص زیادی در وب هست برای همین اینجا می‌خوام یکبار برای همیشه یک شرح کاملی از هر چیزی که لازم و ضروری هست که بدونید بگم. قبلش بهتره کمی در مورد این که ESLint چی هست و اصلا به چه دردی می‌خوره و آیا ما نیاز داریم که باشه یا نه، بدونیم و بعد بریم سراغ دستورالعمل قدم به قدم نصب، راه اندازی و استفاده ازش.

کانفیگ کامل ESLint برای React و Next JS
کانفیگ کامل ESLint برای React و Next JS


این ESLint چی هست و به چه دردی می‌خوره؟

کلمه lint معنی پرز یا ضایعات پنبه یا شاید در دید کلی‌تر به معنی خورده ضایعات حاشیه انجام کار معنی پیدا کنه. در اینجا وقتی می‌گیم یک ابزار یا پکیج lint استفاده می‌کنیم یعنی ما قصد داریم تا یک ناظر به پروژه اضافه کنیم، واسش یکسری قوانینی که دوست داریم رعایت بشه رو بگیم و کار ما رو بررسی کنه تا اگر خارج از اون قوانین رفتار کردیم بمون هشدار و خطا بده تا رفع کنیم و در نهایت کدی تمیز و روی اصول داشته باشیم. مثلا می‌تونیم برای اون تعریف کنیم که هر بار جایی من یک متغییر تعریف کردم ولی استفاده نکردم خطا بده تا اون رو پاک کنم یا اگر یک switch case تعریف کردم حتما باید بخش default هم داشته باشه تا بدونیم اگر caseها نشدن آخرش باید چی بشه و از این دست قوانین و شرایط.

وقتی می‌گیم lint کردن معنی این میده که کد بررسی بشه و هر چیزی که با قوانین تعریف شده ما مطابقت نداشت به شکل خطا یا هشدار در کنسول به ما نمایش داده بشه. اینطور نیاز نیست مدام نگران این باشیم که نکنه جایی چیزی از دستمون در رفته و جلوی خطای انسانی هم گرفته میشه.

پکیج‌های زیادی برای این کار هست ولی یکی از بهترین‌هاش ESLint هست.

نصب و تنظیم ESLint برای Next JS

با دستور زیر پکیج eslint رو نصب می‌کنیم.

npm install --save-dev eslint

حالا وقت این هست که فایلی با نام eslintrc.json. رو در ریشه پروژه ایجاد کنیم تا در اون قوانینی که دوست داریم رو تعریف کنیم. البته راه ساده‌تری هم هست، استفاده از generator خود eslint. با اجرا یکی از دستورات زیر از شما سوالاتی در مورد قوانین می‌پرسه و بعد فایل رو با اون قوانینی که گفتید میسازه.

npx eslint --init

با کلید‌های بالا پایین کیبورد می‌تونید بین گزینه‌ها جا به جا بشید و با زدن enter انتخابشون کنید. گزینه‌های زیر رو به ترتیب انتخاب کنید:

  • To check syntax and find problems
  • JavaScript modules (import/export)
  • React
  • yes (اگر از تایپ‌اسکریپت استفاده می‌‌کنید) / no (استفاده نمی‌کنید)
  • Browser
  • JSON
  • YES

الان پکیج‌های وابسته لازم نصب میشه و فایل کانفیگ در ریشه برنامه با قوانینی که گفتیم ساخته میشه که مقادیر زیر رو در خودش داره ( اگر بدشانسی اوردید و نصب eslint-plugin-react در مرحله آخرش به خطا خورد، خودتون دستی نصبش کنید):

{
    "env": {
        "browser": true,
        "es2021": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended"
    ],
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 12,
        "sourceType": "module"
    },
    "plugins": [
        "react"
    ],
    "rules": {
    }
}


تنظیمات تکمیلی

الان وقت این هست که تنظیمات لازم برای Next JS رو به فایل تنظیماتمون اضافه کنیم. راه ساده‌ترش این هست که فایل eslintrc.json. ایجاد شده در ریشه رو باز کنید و هر چه در اون هست رو با تنظیمات زیر جایگزین کنید و بعد توضیحاتی که در ادامه دادم رو بخونید تا بدونید اینایی که اضافه کردیم چیه.

{
    "settings": {
        "react": {
            "version": "detect"
        }
    },
    "env": {
        "browser": true,
        "es2021": true,
        "node": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended"
    ],
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true
        },
        "ecmaVersion": 12,
        "sourceType": "module"
    },
    "plugins": [
        "react"
    ],
    "rules": {
        "react/prop-types": "off",
        "react/react-in-jsx-scope": "off"
    }
}



توضیح تنظیمات تکمیلی

احتمالا از نسخه ۱۷ React دارید استفاده می‌کنید پس لازم نیست react رو در همه صفحات import کنید ولی اگر نکنید ESLint گیر میده پس rule زیر رو اضافه کردیم:

"react/react-in-jsx-scope": "off"

از طرفی چون نمی‌خوایم در همه کامپوننت‌های از prop-types استفاده کنیم یا ممکن هست typescript داشته باشیم rule زیر رو هم اضافه کردیم (آگر لازم می‌دونید اینو نادیده بگیرید):

"react/prop-types": "off"

این هشدار رو در کنسول داشتیم:

Warning: React version not specified in eslint-plugin-react settings

پس در تنظیمات شناسایی ورژن React رو هم اضافه کردیم:

"settings": {
       "react": {
             "version": "detect"
        }
}

چون در Next JS بحث Server Side Rendering رو داریم در envها node رو هم اضافه کردیم.


  "env": {
       "node": true,
       ....



نادیده گرفتن فایل‌های غیرضروری

طبیعتا دوست نداریم پکیج‌هایی که نصب کردیم رو ESLint بررسی کنه پس باید ignore کنیم. همچنین دایرکتوری‌های .next و out رو پس یک فایل در ریشه پروژه با نام eslintignore. می سازیم و در اون این دایکتوری‌ها رو تعریف می‌کنیم.

**/node_modules/*
**/out/*
**/.next/*



تعریف Script اجرایی

حالا باید در فایل package.json در بخش scripts یک دستور تعریف کنیم تا وقتی اجرا کردیم عملیات lint کردن کل پروژه انجام بشه.

 "scripts": {
      ...
     "lint": "eslint ./ --ext js,jsx,ts,tsx"
}


الان اگر در terminal پروژه دستور زیر رو اجرا کنید می‌تونید خروجی علمیات بررسی ESLint رو مشاهده کنید.

npm run lint



تعریف اجرای اتوماتیک در هنگام توسعه

قاعدتا جالب نیست مدام دستور رو دستی اجرا کنیم و دوست داریم وقتی داریم یک کامپوننت رو توسعه میدیم همزمان عملیات lint کردن هم اتفاق بیفته تا ما حین توسعه متوجه اشتباهات بشیم و رفع کنیم. برای این کار باید تنظیمات webpack رو از طریق فایل next.config.js رو توسعه بدیم. (این فایل احتمالا در ریشه پروژه موجود باشه و اگر نیست ایجادش کنید). البته بهتره بدونید تنها فایل‌هایی که مرورگر به اونها درخواست بزنه lint میشه و تنها راه برای بررسی کل پروژه به طور کامل همون دستور بالاست. جای نگرانی نیست چون در حالت واقعی همیشه ما وقتی توسعه میدیم اون صفحه رو هم اجرا میکنیم تا تغییرات رو ببینم پس کم پیش میاد اتفاقی از دیدمون مخفی بشه و فقط برای اطمینان لازم هست قبل production build یک بار دستور بررسی سراسری رو اجرا کنید تا چیزی از قلم نیفته.

با webpack 4 و eslint-loader

اگر از 4 webpack استفاده می‌کنید باید ابتدا eslint-loader رو نصب کنید:

npm install eslint-loader --save-dev

و بعد تنظیمات زیر رو در فایل next.config.js بذارید. این تنظیمات باعث میشه تا eslint-loader با تغییر فایل‌ها و اجرا لودرهای مربوط به ترنسپایل اسکریپت‌ها هم اجرا بشه.

module.exports = {
    webpack: (config, { dev }) => {
        if (dev) {
            config.module.rules.push({
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'eslint-loader',
                options: {
                    // Emit errors as warnings for dev to not break webpack build.
                    // Eslint errors are shown in console for dev, yay :-)
                    emitWarning: dev,
                }
            })
        }
        return config
    }
}

البته eslint-loader در webpack 5 منسوخ شده و باید از روش زیر استفاده کنید.

با webpack 5 و eslint-webpack-plugin

اگر از 5 webpack استفاده می‌کنید باید ابتدا eslint-webpack-plugin رو نصب کنید:

npm install eslint-webpack-plugin --save-dev

حالا باید تنظیمات زیر و در فایل next.config.js بذارید.این تنظیمات باعث میشه تا eslint-webpack-plugin با تغییر فایل‌ها و اجرا لودرهای مربوط به ترنسپایل اسکریپت‌ها هم اجرا بشه.

const ESLintPlugin = require("eslint-webpack-plugin");
module.exports = {
    future:  {
        webpack5: true,
    },
    webpack: (config, {dev}) => {
        if (dev) 
            config.plugins.push(new ESLintPlugin());
        return config;
    }
};


جلوگیری از commit

فکر نکنم کسی دوست داشته باشه در حالی که چندتا خطا و هشدار eslint رو داریم اون رو در repository git commit کنیم. برای اتصال git به eslint و اجرا اون قبل هر کامیت از hookهای git میشه استفاده کرد. ابزاری جذاب به نام husky هست که دقیقا همین خواسته ما رو به خوبی انجام میده. پس بریم برای نصب و کانفیگش(اینجا روش‌های اتوماتیک و دستی نصب و کانفیگ هاسکی رو کامل گفته ولی در ادامه روشی که خودم بهتر دیدم رو می‌گم).

قبل هر چیز husky رو نصب می‌کنیم:

npm i -D husky

حالا باید اسکریپتی به نام prepare رو در package.json ایجاد کنیم تا طی اون git hookها ساخته بشه. ساده‌ترین راه اجرا این دستور هست. بعد این هم script فایل package.json ساخته میشه هم دستور اجرا میشه که حاصل اون میشه ایجاد دایرکتوری husky. در ریشه پروژه و تنظیمات لازم اتصالات git hook. (دقت کنید که دستور set-script در ورژن 7 به بعد npm موجود هست و اگر ورژن npm رو دوست ندارید اپدیت کنید باید خودتون scriptی با نام prepare و دستور اجرایی husky install رو در package.json تعریف و بعد فقط npm run prepare رو اجرا کنید.)

npm set-script prepare "husky install" && npm run prepare

الان کانفیگ پایه هاسکی انجام شده و فقط کافی هست دستوری که می‌خوایم قبل هر کامیت اجرا بشه و اگر همه چی اوکی بود اون وقت کامیت ثبت بشه رو ایجاد کنیم. برای این کار کافی هست دستور زیر رو اجرا کنید:

npx husky add .husky/pre-commit "npm run lint"

این دستور فایلی به نام pre-commit در دایرکتوی husky. ایجاد می‌کنه که در اون دستور npm run lint ثبت شده تا قبل هر کامیت اجرا بشه.

دقت کنید که تنظیمات پایه در gitignore. ثبت شده پس اگر کسی پروژه رو clone کرد برای ایجاد این تنظیمات پایه باید ابتدا دستور زیر رو اجرا کنه.

npm run prepare


جمع بندی

در ابتدا eslint رو یکسری تنظیمات اولیه نصب و راه اندازی کردیم، بعد یکسری تنظیمات بیشتر برای Next JS و React به اون اضافه کردیم. بعد مواردی که نمی‌خواستیم در lint بیاد رو مشخص کردیم. در ادامه رسیدیم به ایجاد اسکریپت اجرایی و اجرای eslint طی عملیات توسعه و در آخر به کمک husky اون رو به git هم متصل کردیم تا اشتباهات قبل کامیت کردن رفع بشن. بعد اینها میشه گفت همه کارهای لازم برای یک توسعه خوب رو کردیم ولی شاید پایان پایان نباشه، شما می‌تونید در مورد قوانین و تنظیمات eslint بیشتر مطالعه کنید و اونها رو در فایل کانفیگش اضافه کنید مثلا با اضافه کردن قانون زیر به بخش rule شما مجبور خواهید شد همه‌جای پروژه stringها رو با double quotes بنویسید و اگر جایی با single quotes بنویسید به خطا می‌خورید.

"quotes": ["error", "double"]