1. npx create-react-app project-name & cd project-name
2. npm install eslint-plugin-react eslint-config-airbnb eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-react-hooks eslint-config-prettier eslint-plugin-prettier prettier stylelint stylelint-scss stylelint-config-airbnb stylelint-order stylelint-config-idiomatic-order stylelint-prettier stylelint-config-prettier husky lint-staged node-sass --save-dev
3. npm install redux react-redux redux-thunk react-router-dom axios bootstrap react-bootstrap date-fns prop-types react-custom-scrollbars react-select react-datepicker react-text-mask react-toastify formik yup jwt-decode
4. touch .editorconfig & nano .editorconfig
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 100
trim_trailing_whitespace = true
[*.md]
max_line_length = 0
trim_trailing_whitespace = false
[{package.json,.travis.yml}]
indent_style = space
indent_size = 2
[{Makefile,**.mk}]
indent_style = tab
5. touch .eslintrc.json & nano .eslintrc.json
{
"env": {
"browser": true,
"es6": true
},
"extends": ["react-app", "airbnb", "plugin:jsx-a11y/recommended", "prettier", "prettier/react"],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parser": "babel-eslint",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": ["react", "jsx-a11y", "prettier"],
"rules": {
"prettier/prettier": "error",
"no-unused-vars": "warn",
"react/jsx-filename-extension": [
"warn",
{
"extensions": [".js"]
}
],
"no-console": [
"warn",
{
"allow": ["warn", "error", "info"]
}
],
"no-shadow": "off",
"react/state-in-constructor": [2, "never"],
"max-len": [
"warn",
{
"code": 100,
"tabWidth": 2,
"comments": 100,
"ignoreComments": false,
"ignoreTrailingComments": true,
"ignoreUrls": true,
"ignoreStrings": true,
"ignoreTemplateLiterals": true,
"ignoreRegExpLiterals": true
}
]
}
}
6. touch .stylelintrc.json & nano .stylelintrc.json
{
"extends": [
"stylelint-config-airbnb",
"stylelint-config-idiomatic-order",
"stylelint-prettier/recommended"
],
"plugins": ["stylelint-order", "stylelint-scss"],
"rules": {
"max-nesting-depth": 5
}
}
7. touch .env & nano .env
EXTEND_ESLINT=true
8. touch .prettierrc & nano .prettierrc
{
"singleQuote": true
}
9. touch .huskyrc.json & nano .huskyrc.json
{
"hooks": {
"pre-commit": "lint-staged"
}
}
10. touch .lintstagedrc.json & nano .lintstagedrc.json
{
"src/**/*.{js,jsx}": "eslint --fix",
"src/**/*.{css,scss}": "stylelint --fix",
"**/*.{json,md}": "prettier --write"
}
11. В package.json удалить поле eslintConfig
{
"workbench.iconTheme": "material-icon-theme",
"workbench.colorTheme": "One Dark Pro",
"editor.tabSize": 2,
"window.zoomLevel": 1,
"editor.renderWhitespace": "boundary",
"material-icon-theme.hidesExplorerArrows": true,
"material-icon-theme.folders.theme": "classic",
"workbench.sideBar.location": "right",
"editor.minimap.enabled": false,
"scss.validate": false,
"css.validate": false,
"less.validate": false,
"eslint.alwaysShowStatus": true,
"eslint.format.enable": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.stylelint": true
},
// "editor.formatOnSave": true,
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
// "editor.defaultFormatter": "esbenp.prettier-vscode"
},
"javascript.format.enable": false,
"javascript.validate.enable": false,
"files.associations": {
"*.jsx": "javascriptreact",
"*.js": "javascriptreact"
},
"emmet.syntaxProfiles": {
"javascript": "jsx"
},
"prettier.disableLanguages": ["js"],
"javascript.updateImportsOnFileMove.enabled": "never",
}