
من در ابتدا نصب و کانفیگ ESLint رو به شما آموزش میدم و همچنین بهتون میگم که چطور میتونید قبل از commit کردن روی گیت قوانین ESLint رو به طور خودکار بررسی کنید و بعد از اون به سراغ اکستنشن Prettier میرم و بهتون میگم که چطوری میتونین اون رو با ESLint پروژتون integrate کنید، که با هر بار ذخیره فایلهای پروژتون تمامی قوانین به طور خودکار اعمال بشه
ESLint 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 ای مفیدی که من به پروژم اضاف کردم ایناست:
اگه توی پروژتون از TypeScript استفاده میکنید، دو تا پلاگین زیر بدردتون میخوره
با استفاده از دستور زیر تمامی پلاگینها و پیشنیازهای 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 که با استفاده از یک الگوی مشخص بهش میگین که نام فایلهای پروژم از این ساختار خارج نشه، برای مثال نام چندتا از فایلهای من به این شکله:
{ "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
شما با استفاده از pre-commit میتونید به صورت خودکار قوانین ESLint رو قبل از اینکه دولاپری بخواد کامیتش رو انجام بده بررسی کنید و اگه error ای در قوانین باشه جلوی کامیتش رو بگیرید.
"scripts": { "precommit-msg": "echo 'Pre-commit checks...' && exit 0" }, "pre-commit": [ "precommit-msg", "lint" ]
Prettier 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.
https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
yarn add -D prettier-eslint-cli
{ "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/settings.json
{ "prettier.eslintIntegration": true, "editor.formatOnSave": true }
خط اول برای integration اکستنشن Prettier با ESLint و خط دوم برای اینکه بعد از هر بار فشردن کلیدهای Ctrl + S اکستنشن Prettier به طور خودکار اجرا بشه.
اگه سوالی راجب rule های ESLint من داشتین، میتونید در قسمت کامنتها ازم بپرسین