ESLint و Prettier برای React

من در ابتدا نصب و کانفیگ ESLint رو به شما آموزش میدم و همچنین بهتون میگم که چطور میتونید قبل از commit کردن روی گیت قوانین ESLint رو به طور خودکار بررسی کنید و بعد از اون به سراغ اکستنشن Prettier میرم و بهتون میگم که چطوری میتونین اون رو با ESLint پروژتون integrate کنید، که با هر بار ذخیره فایل‌های پروژتون تمامی قوانین به طور خودکار اعمال بشهنصب و کانفیگ ESLintESLint is an open source project originally created by Nicholas C. Zakas in June 2013. Its goal is to provide a pluggable linting utility for JavaScript.شما با استفاده از ESLint میتونین دولاپرها رو مقید کنید از یک سری اصول و قوانین در هنگام کد زدن پیروی کنن و از مسیر خارج نشن، به این کار اصطلاحاً Linting می‌گویند.نصبپلاگین‌های ESLint ای مفیدی که من به پروژم اضاف کردم ایناست:eslint-plugin-babeleslint-plugin-css-modules : برای سی‌اس‌اس ماژولeslint-plugin-filenames : برای ساختار و نام فایل‌ها، بهش الگو میدینeslint-plugin-flowtypeeslint-plugin-importeslint-plugin-no-async-without-await : اینم که از اسمش مشخصهeslint-plugin-react : برای خود ری‌اکتeslint-plugin-react-hooks : برای ری‌اکت هوکeslint-plugin-react-redux : برای ریداکسeslint-plugin-redux-saga : برای ریداکس ساگاeslint-plugin-simple-import-sort : برای مرتب سازی ایمپورت‌های خارجی و داخلی پروژتوناگه توی پروژتون از TypeScript استفاده میکنید، دو تا پلاگین زیر بدردتون میخوره@typescript-eslint/eslint-plugin@typescript-eslint/parserبا استفاده از دستور زیر تمامی پلاگین‌ها و پیش‌نیازهای ESLint رو نصب می‌کنیم.yarn add -D eslint babel-eslint eslint-config-react-app eslint-loader eslint-plugin-babel eslint-plugin-react eslint-plugin-css-modules eslint-plugin-filenames eslint-plugin-flowtype eslint-plugin-import eslint-plugin-no-async-without-await eslint-plugin-react-hooks eslint-plugin-react-redux eslint-plugin-redux-saga eslint-plugin-simple-import-sortکانفیگحالا یک فایل با نام .eslintrc در روت پروژتون ایجاد کنید و به شکل زیر ESLint رو کانفیگ کنید.{ "env": { "browser": true, "es6": true, "node": true }, "settings": { "react": { "version": "detect" } }, "plugins": [ "babel", "react", "react-hooks", "react-redux", "redux-saga", "no-async-without-await", "css-modules", "filenames", "simple-import-sort" ], "extends": [ "react-app", "plugin:react/recommended", "plugin:@typescript-eslint/recommended", "plugin:react-redux/recommended", "plugin:redux-saga/recommended", "plugin:css-modules/recommended" ], "parser": "@typescript-eslint/parser", "globals": { "Atomics": "readonly", "SharedArrayBuffer": "readonly" }, "parserOptions": { "ecmaFeatures": { "jsx": true }, "ecmaVersion": 2018, "sourceType": "module" }, "rules": { "strict": ["error", "safe"], "no-debugger": "error", "brace-style": [ "error", "1tbs", { "allowSingleLine": true } ], "no-trailing-spaces": "error", "keyword-spacing": "error", "space-before-function-paren": ["error", "never"], "spaced-comment": ["error", "always"], "vars-on-top": "error", "no-undef": "error", "no-undefined": "warn", "comma-dangle": ["error", "never"], "quotes": ["error", "single"], "semi": ["error", "always"], "guard-for-in": "error", "no-eval": "error", "no-with": "error", "valid-typeof": "error", "no-unused-vars": "error", "no-continue": "warn", "no-extra-semi": "warn", "no-unreachable": "warn", "no-unused-expressions": "warn", "max-len": ["warn", 80, 4], "react/prefer-es6-class": "warn", "react/jsx-boolean-value": "warn", "react-hooks/rules-of-hooks": "error", "react-hooks/exhaustive-deps": "warn", "@typescript-eslint/indent": ["error", 2], "@typescript-eslint/no-explicit-any": "off", "react/prop-types": "off", "react-redux/mapDispatchToProps-returns-object": "off", "react-redux/prefer-separate-component-file": "off", "@typescript-eslint/explicit-function-return-type": [ "warn", { "allowExpressions": true } ], "no-async-without-await/no-async-without-await": "warn", "css-modules/no-undef-class": "off", "filenames/match-regex": [ "error", "^[a-zA-Z]+\\.*\\b(typescript|module|locale|validate|test|action|api|reducer|saga)?\\b$", true ], "filenames/match-exported": "off", "filenames/no-index": "error", "simple-import-sort/sort": "error" } }اجازه بدین قبل از اینکه بریم سراغ مرحله بعد یه توضیح کوتاهی راجب کانفیگ بالا بدم.قسمت plugins که مشخصه، همون لیستی ایه که اون بالا معرفی کردم، شما از طریق extends میتونید یکسری rule هایی که خود پلاگین‌ها به صورت پیشنهادی نوشتن رو به rule های پروژتون extend کنید.قسمت parserOptions برای اینکه بهش بگین من از ecmaVersion 2018 استفاده میکنم و قسمت مهم داستان هم rule هاست که از طریق سه نوع type با نام‌های error، warn و off می‌تونید سطح اجباری بودن و نبودن و rule هارو تعیین کنید.یکی از rule هایی که شاید فقط مختص پروژه خودم باشه و خودمم خیلی دوسش دارم رو اجازه بدین واستون یه توضیح کوتاهی راجبش بدم، رول filenames/match-regex که با استفاده از یک الگوی مشخص بهش میگین که نام فایل‌های پروژم از این ساختار خارج نشه، برای مثال نام چندتا از فایل‌های من به این شکله:Login.tsxLogin.module.scssLogin.locale.tsxLogin.reducer.tsx...کانفیگ اسکریپت ESLint در package.json{ "scripts": { "lint": "./node_modules/.bin/eslint src --ext .js,.jsx,.ts,.tsx", "lint:fix": "./node_modules/.bin/eslint src --ext .js,.jsx,.ts,.tsx --fix" } }طرز استفاده از اسکریپت بالا در خط فرمان به این شکلهyarn lint yarn lint:fix // OR npm run lint npm run lint:fixکانفیگ ESLint برای pre-commitشما با استفاده از pre-commit میتونید به صورت خودکار قوانین ESLint رو قبل از اینکه دولاپری بخواد کامیتش رو انجام بده بررسی کنید و اگه error ای در قوانین باشه جلوی کامیتش رو بگیرید."scripts": { "precommit-msg": "echo 'Pre-commit checks...' && exit 0" }, "pre-commit": [ "precommit-msg", "lint" ]نصب و کانفیگ PrettierPrettier is an opinionated code formatter. It enforces a consistent style by parsing your code and re-printing it with its own rules that take the maximum line length into account, wrapping code when necessary.اکستنشن Prettier برای VSCodehttps://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscodeخط فرمان Prettieryarn add -D prettier-eslint-cli کانفیگ اسکریپت Prettier در package.json{ "scripts": { "prettier": "./node_modules/.bin/prettier-eslint \"src/**/*.tsx\"", "prettier:fix": "./node_modules/.bin/prettier-eslint --write \"src/**/*.tsx\" \"src/**/*.ts\"", } }طرز استفاده از اسکریپت بالا در خط فرمان به این شکلهyarn prettier yarn prettier:fix // OR npm run prettier npm run prettier:fixکانفیگ VSCode برای ESLint و Prettierفایل زیر رو در روت پروژه ایجاد و خطوط زیر رو در اون اضاف کنید..vscode/settings.json{ "prettier.eslintIntegration": true, "editor.formatOnSave": true }خط اول برای integration اکستنشن Prettier با ESLint و خط دوم برای اینکه بعد از هر بار فشردن کلیدهای Ctrl + S اکستنشن Prettier به طور خودکار اجرا بشه.اگه سوالی راجب rule های ESLint من داشتین، میتونید در قسمت کامنت‌ها ازم بپرسین