├── README.md └── eslint-prettier-config.sh /README.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | 1. Navigate to your app directory where you want to include this style configuration. 4 | 5 | ```bash 6 | cd my-app 7 | ``` 8 | 9 | 2. Run this command inside your app's root directory. Note: this command executes the `eslint-prettier-config.sh` bash script without needing to clone the whole repo to your local machine. 10 | 11 | ```bash 12 | exec 3<&1;bash <&3 <(curl https://raw.githubusercontent.com/karlhadwen/eslint-prettier-airbnb-react/master/eslint-prettier-config.sh 2> /dev/null) 13 | ``` 14 | -------------------------------------------------------------------------------- /eslint-prettier-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # ---------------------- 4 | # Color Variables 5 | # ---------------------- 6 | RED="\033[0;31m" 7 | YELLOW='\033[1;33m' 8 | GREEN='\033[1;32m' 9 | LCYAN='\033[1;36m' 10 | NC='\033[0m' # No Color 11 | 12 | # -------------------------------------- 13 | # Prompts for configuration preferences 14 | # -------------------------------------- 15 | 16 | # Package Manager Prompt 17 | echo 18 | echo "Which package manager are you using?" 19 | select package_command_choices in "Yarn" "npm" "Cancel"; do 20 | case $package_command_choices in 21 | Yarn ) pkg_cmd='yarn add'; break;; 22 | npm ) pkg_cmd='npm install'; break;; 23 | Cancel ) exit;; 24 | esac 25 | done 26 | echo 27 | 28 | # File Format Prompt 29 | echo "Which ESLint and Prettier configuration format do you prefer?" 30 | select config_extension in ".js" ".json" "Cancel"; do 31 | case $config_extension in 32 | .js ) config_opening='module.exports = {'; break;; 33 | .json ) config_opening='{'; break;; 34 | Cancel ) exit;; 35 | esac 36 | done 37 | echo 38 | 39 | # Checks for existing eslintrc files 40 | if [ -f ".eslintrc.js" -o -f ".eslintrc.yaml" -o -f ".eslintrc.yml" -o -f ".eslintrc.json" -o -f ".eslintrc" ]; then 41 | echo -e "${RED}Existing ESLint config file(s) found:${NC}" 42 | ls -a .eslint* | xargs -n 1 basename 43 | echo 44 | echo -e "${RED}CAUTION:${NC} there is loading priority when more than one config file is present: https://eslint.org/docs/user-guide/configuring#configuration-file-formats" 45 | echo 46 | read -p "Write .eslintrc${config_extension} (Y/n)? " 47 | if [[ $REPLY =~ ^[Nn]$ ]]; then 48 | echo -e "${YELLOW}>>>>> Skipping ESLint config${NC}" 49 | skip_eslint_setup="true" 50 | fi 51 | fi 52 | finished=false 53 | 54 | # Max Line Length Prompt 55 | while ! $finished; do 56 | read -p "What max line length do you want to set for ESLint and Prettier? (Recommendation: 100)" 57 | if [[ $REPLY =~ ^[0-9]{2,3}$ ]]; then 58 | max_len_val=$REPLY 59 | finished=true 60 | echo 61 | else 62 | echo -e "${YELLOW}Please choose a max length of two or three digits, e.g. 80 or 100 or 120${NC}" 63 | fi 64 | done 65 | 66 | # Trailing Commas Prompt 67 | echo "What style of trailing commas do you want to enforce with Prettier?" 68 | echo -e "${YELLOW}>>>>> See https://prettier.io/docs/en/options.html#trailing-commas for more details.${NC}" 69 | select trailing_comma_pref in "none" "es5" "all"; do 70 | case $trailing_comma_pref in 71 | "none" ) break;; 72 | "es5" ) break;; 73 | "all" ) break;; 74 | esac 75 | done 76 | echo 77 | 78 | # ---------------------- 79 | # Perform Configuration 80 | # ---------------------- 81 | echo 82 | echo -e "${GREEN}Configuring your development environment... ${NC}" 83 | 84 | echo 85 | echo -e "1/4 ${LCYAN}ESLint & Prettier Installation... ${NC}" 86 | echo 87 | $pkg_cmd -D eslint prettier eslint-plugin-react-hooks 88 | 89 | echo 90 | echo -e "2/4 ${YELLOW}Conforming to Airbnb's JavaScript Style Guide... ${NC}" 91 | echo 92 | $pkg_cmd -D eslint-config-airbnb eslint-plugin-jsx-a11y eslint-plugin-import eslint-plugin-react babel-eslint 93 | 94 | echo 95 | echo -e "3/4 ${LCYAN}Making ESlint and Prettier play nice with each other... ${NC}" 96 | echo "See https://github.com/prettier/eslint-config-prettier for more details." 97 | echo 98 | $pkg_cmd -D eslint-config-prettier eslint-plugin-prettier 99 | 100 | 101 | if [ "$skip_eslint_setup" == "true" ]; then 102 | break 103 | else 104 | echo 105 | echo -e "4/4 ${YELLOW}Building your .eslintrc${config_extension} file...${NC}" 106 | > ".eslintrc${config_extension}" # truncates existing file (or creates empty) 107 | 108 | echo ${config_opening}' 109 | "extends": [ 110 | "airbnb", 111 | "prettier", 112 | "plugin:jsx-a11y/recommended", 113 | "plugin:react-hooks/recommended" 114 | ], 115 | "parser": "babel-eslint", 116 | "parserOptions": { 117 | "ecmaVersion": 8, 118 | "ecmaFeatures": { 119 | "experimentalObjectRestSpread": true, 120 | "impliedStrict": true, 121 | "classes": true 122 | } 123 | }, 124 | "env": { 125 | "browser": true, 126 | "node": true, 127 | "jquery": true, 128 | "jest": true 129 | }, 130 | "rules": { 131 | "react-hooks/rules-of-hooks": "error", 132 | "no-debugger": 0, 133 | "no-alert": 0, 134 | "no-unused-vars": 1, 135 | "prefer-const": [ 136 | "error", 137 | { 138 | "destructuring": "all" 139 | } 140 | ], 141 | "arrow-body-style": [ 142 | 2, 143 | "as-needed" 144 | ], 145 | "no-unused-expressions": [ 146 | 2, 147 | { 148 | "allowTaggedTemplates": true 149 | } 150 | ], 151 | "no-param-reassign": [ 152 | 2, 153 | { 154 | "props": false 155 | } 156 | ], 157 | "no-console": 0, 158 | "import/prefer-default-export": 1, 159 | "import": 0, 160 | "func-names": 0, 161 | "space-before-function-paren": 0, 162 | "comma-dangle": 0, 163 | "max-len": 0, 164 | "import/extensions": 0, 165 | "no-underscore-dangle": 0, 166 | "consistent-return": 0, 167 | "react/display-name": 1, 168 | "react/no-array-index-key": 0, 169 | "react/react-in-jsx-scope": 0, 170 | "react/prefer-stateless-function": 0, 171 | "react/forbid-prop-types": 0, 172 | "react/jsx-props-no-spreading": 0, 173 | "react/no-unescaped-entities": 0, 174 | "jsx-a11y/accessible-emoji": 0, 175 | "react/require-default-props": 0, 176 | "react/jsx-filename-extension": [ 177 | 1, 178 | { 179 | "extensions": [ 180 | ".js", 181 | ".jsx" 182 | ] 183 | } 184 | ], 185 | "radix": 0, 186 | "no-shadow": "off", 187 | "quotes": [ 188 | 2, 189 | "single", 190 | { 191 | "avoidEscape": true, 192 | "allowTemplateLiterals": true 193 | } 194 | ], 195 | "prettier/prettier": [ 196 | "error", 197 | { 198 | "trailingComma": "'${trailing_comma_pref}'", 199 | "singleQuote": true, 200 | "printWidth": '${max_len_val}' 201 | } 202 | ], 203 | "jsx-a11y/href-no-hash": "off", 204 | "jsx-a11y/anchor-is-valid": [ 205 | "warn", 206 | { 207 | "aspects": [ 208 | "invalidHref" 209 | ] 210 | } 211 | ] 212 | }, 213 | "plugins": [ 214 | "prettier", 215 | "react", 216 | "react-hooks" 217 | ] 218 | }' >> .eslintrc${config_extension} 219 | fi 220 | 221 | echo 222 | echo -e "${GREEN}Finished setting up!${NC}" 223 | echo 224 | --------------------------------------------------------------------------------