Welcome to my tutorial on setting up React projects! With a plethora of resources available, I wanted to share my personal approach. As my focus lies mainly in constructing internal web applications that don't require SSR or SSG and the full suite of Next.js features, I prefer leveraging Vite - an excellent alternative to frameworks like Next.js.
Let's dive right into the tutorial! 💻🚀
Prerequisites
Before we dive in, make sure you have the following software installed on your machine:
- Node.js
- npm (Node Package Manager)
Step 1: Initializing a New React Project
To create a new React project with Vite and TypeScript, open your command line interface and navigate to your desired directory. Execute the following command:
npm create vite@latest my-react-app -- --template react-ts
This command generates a new directory called my-react-app
with a basic React project structure and TypeScript configurations.
Step 2: Installing Project Dependencies
Navigate to the project directory:
cd my-react-app
Next, install the project dependencies using npm:
npm install
This command installs the necessary dependencies specified in the project's package.json
file.
Step 3: Starting the Development Server
Once the dependencies are installed, start the development server with the following command:
npm run dev
This command launches the Vite development server, and you can access your project at http://localhost:5173
. Any modifications you make to your React components or other project files will trigger hot module replacement (HMR), allowing for efficient development.
Step 4: Configuring ESLint
To set up ESLint with the Airbnb configuration, execute the following command:
npx install-peerdeps --dev eslint-config-airbnb
Next, install the Airbnb configuration for TypeScript:
npm install --save-dev eslint-config-airbnb-typescript
Copy and paste the code below into your .eslintrc.cjs
file:
module.exports = {
env: { browser: true, es2020: true },
extends: [
'airbnb',
'airbnb-typescript',
'airbnb/hooks',
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: './tsconfig.json',
},
plugins: ['react-refresh', 'react', '@typescript-eslint'],
rules: {
'react-refresh/only-export-components': 'warn',
},
};
Copy and paste the code below into your tsconfig.json
file:
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["./.eslintrc.cjs", "src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
Make sure to restart your editor (e.g., VSCode) to resolve any errors in the .eslintrc.cjs
file.
Great! ESLint is now configured, and we'll add some additional options in the upcoming steps.
Step 5: Setting up Prettier
To install Prettier along with the necessary ESLint plugins and configurations, use the following command:
npm i --save-dev prettier eslint-config-prettier eslint-plugin-prettier
Create a new file named .prettierrc
in the project's root directory and paste the following code into it:
{
"semi": true,
"tabWidth": 2,
"printWidth": 100,
"singleQuote": true,
"trailingComma": "es5"
}
Next, update the .eslintrc.cjs
file by adding Prettier to it:
module.exports = {
env: { browser: true, es2020: true },
extends: [
'airbnb',
'airbnb-typescript',
'airbnb/hooks',
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: './tsconfig.json',
},
plugins: ['react-refresh', 'react', '@typescript-eslint', 'prettier'],
rules: {
'react-refresh/only-export-components': 'warn',
},
};
Step 6: Adding Additional ESLint Settings
Copy and paste the code below into your .eslintrc.cjs
file:
module.exports = {
env: { browser: true, es2020: true },
extends: [
'airbnb',
'airbnb-typescript',
'airbnb/hooks',
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
project: './tsconfig.json',
},
plugins: ['react-refresh', 'react', '@typescript-eslint', 'prettier'],
rules: {
'react-refresh/only-export-components': 'warn',
'prettier/prettier': [
'error',
{
endOfLine: 'auto',
},
],
'@typescript-eslint/no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
],
'react/react-in-jsx-scope': 'off',
'react/jsx-props-no-spreading': 'off',
'import/prefer-default-export': 'off',
'import/extensions': 'off',
'react/require-default-props': 'off',
'react/function-component-definition': [
'error',
{
namedComponents: 'arrow-function',
},
],
},
};
Each rule serves a specific purpose:
'react-refresh/only-export-components': 'warn'
: Issues a warning if React components are exported in a suboptimal manner for Fast Refresh.'prettier/prettier': ['error', { endOfLine: 'auto' }]
: Enforces consistent code formatting using Prettier. It generates an error if the code formatting doesn't match the Prettier configuration.'@typescript-eslint/no-unused-vars': ['warn', {argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrorsIgnorePattern: '^_' }]
: Warns about unused variables in TypeScript but allows names starting with an underscore (_) to be ignored.'react/react-in-jsx-scope': 'off'
: Disables the requirement to import React in every file that uses JSX since it's automatically imported with the JSX transform.'react/jsx-props-no-spreading': 'off'
: Disables the warning for spreading props ({...props}) in JSX components, allowing this practice.'import/prefer-default-export': 'off'
: Disables the preference for default exports when only one export is present, allowing named exports.'import/extensions': 'off'
: Disables the requirement to include file extensions in import statements.'react/require-default-props': 'off'
: Disables the requirement for default values in prop types, allowing optional props.'react/function-component-definition': ['error', { namedComponents: 'arrow-function' }]
: Enforces the use of arrow function syntax for defining function components in React.
These rules help maintain code consistency, catch potential issues, and configure ESLint to work well with React, TypeScript, and Prettier.
Step 7: Adding VSCode Settings
Create a new folder named .vscode
in the project's root directory. Inside this folder, create a new file named settings.json
and paste the following code:
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.tabSize": 2,
"prettier.singleQuote": true,
"files.eol": "\n"
}
These settings configure your Visual Studio Code editor to use the Prettier extension as the default formatter, enable formatting on save, set the tab size to 2 spaces, enforce single quotes, and use Unix-style line endings.
Step 8: Adding Support for Absolute Paths
Install the dev dependency vite-tsconfig-paths
using the following command:
npm i --save-dev vite-tsconfig-paths
Open the vite.config.ts file
and copy-paste the code below (ignore any TypeScript errors you may encounter):
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tsConfigPaths from 'vite-tsconfig-paths';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), tsConfigPaths()],
});
Open the tsconfig.json
file and copy-paste the code below:
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["./.eslintrc.cjs", "src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
Congratulations! You can now use absolute imports throughout your app. Instead of using relative paths like import Button from '../../../../components/Button'
, you can use concise absolute paths like import Button from '@/components/Button'
if your Button
component is located in the src/components
directory.
Step 9 (optional): Adding a .gitignore
File
If necessary, create a .gitignore
file in the project's root directory and add the following code:
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
node_modules
.pnp
.pnp.js
# testing
coverage
# production
.next/
out/
dist/
build
# misc
.DS_Store
# *.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# local env files
.env*.local
.env
# typescript
*.tsbuildinfo
next-env.d.ts
Step 10: Congratulations! 🎉
You have successfully set up your project with React, Vite, TypeScript, ESLint, and Prettier! 🥳