React Project Setup

Published on
• 5 min read

Absolute imports

// jsconfig.json
{
"compilerOptions": {
"jsx": "preserve",
"baseUrl": ".",
"paths": {
"@/*": ["*"]
}
},
"exclude": ["node_modules", ".next"]
}

If using Create-React-App, craco needs to be installed

// craco.config.js and baseUrl is `./src`
const path = require('path')
module.exports = {
webpack: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
}

Configure commitlint, eslint and prettier

We'll use husky and lint-staged to configure eslint, prettier, and git. We'll also install commitlint and alex

Run the code belowe to setup husky and create a pre-commit file

npx husky-init && npm i

Using commitlint to impose conventional commits for a better dev experience.

npm i -D @commitlint/config-conventional @commitlint/cli lint-staged prettier

Add another hook to husky

npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

Configure commitlint rules within commitlint.config.js

commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
['feat', 'fix', 'docs', 'chore', 'style', 'refactor', 'ci', 'test', 'revert', 'perf'],
],
},
}

These rules are based on the conventional commits

Key Description
feat Changes about addition or removal of a feature. Ex: feat: add table on landing page, feat: remove table from landing page
fix Bug fixing, followed by the bug. Ex: fix: illustration overflows in mobile view
docs Update documentation (README.md)
style Updating style, and not changing any logic in the code (reorder imports, fix whitespace, remove comments)
chore Installing new dependencies, or bumping deps
refactor Changes in code, same output, but different approach
ci Update github workflows, husky
test Update testing suite, cypress files
revert when reverting commits
perf Fixing something regarding performance (deriving state, using memo, callback)

Add lint-staged scipt to package.json

{
// ...
"lint-staged": {
"*.+(js|jsx|ts|tsx)": ["eslint --fix"],
"*.+(js|jsx|ts|tsx|json|css|md|mdx)": ["prettier --write"]
}
//...
}

Add a pre-commit hook to husky within .husky/pre-commit file

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged

Add a post-merge hook to husky which runs npm i after a merge.

npx husky add .husky/post-merge 'npm i'

Optional dependencies

Install alexjs that helps in phrasing text.

npm i alex --save-dev

eslint plugins

npm i -D \
eslint-plugin-prettier \
@typescript-eslint/parser \
@typescript-eslint/eslint-plugin \
eslint-plugin-react-hooks \
eslint-plugin-sonarjs \

For tailwindcss

prettier-plugin-tailwindcss
module.exports = {
root: true,
env: {
browser: true,
amd: true,
node: true,
es6: true,
},
extends: [
'next/core-web-vitals',
'prettier',
'eslint:recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:sonarjs/recommended',
],
rules: {
'prettier/prettier': [
'warn',
{
endOfLine: 'auto',
},
],
'react/react-in-jsx-scope': 'off',
'react/prop-types': 0,
'no-unused-vars': 0,
'react/no-unescaped-entities': 0,
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
'sonarjs/cognitive-complexity': 'error',
'sonarjs/no-identical-expressions': 'error',
'jsx-a11y/anchor-is-valid': [
'error',
{
components: ['Link'],
specialLink: ['hrefLeft', 'hrefRight'],
aspects: ['invalidHref', 'preferButton'],
},
],
'no-nested-ternary': 'off',
'import/prefer-default-export': 'off',
},
plugins: ['@typescript-eslint', 'react-hooks', 'prettier', 'sonarjs'],
}