DEV Community

Cover image for Optimizing Your React App: A Guide to Production-Ready Setup with Webpack, TypeScript, ESLint, and Prettier - 2024
Shivam Pawar
Shivam Pawar

Posted on • Updated on

Optimizing Your React App: A Guide to Production-Ready Setup with Webpack, TypeScript, ESLint, and Prettier - 2024

In this blog post, we'll cover everything you need to know to set up a React app that's ready for deployment.

GitHub Repo: https://github.com/shivam-pawar/sample-react-app

Prerequisites

Before we begin, make sure you have Node.js and npm (or yarn) installed on your machine.

Initialize a new project

Use your Command Line and navigate to the root folder of your project and enter

npm init
Enter fullscreen mode Exit fullscreen mode

This will ask you some basic information like package name, author name, description, and license. With this info it will create a file called package.json

Install React and TypeScript

  • Install React and ReactDOM as dependencies:
npm install react react-dom
Enter fullscreen mode Exit fullscreen mode
  • Install TypeScript and its types as dev dependencies:
npm install --save-dev typescript @types/react @types/react-dom
Enter fullscreen mode Exit fullscreen mode

Set up Webpack

Install the necessary Webpack dependencies:

npm install --save-dev webpack webpack-cli webpack-dev-server html-webpack-plugin webpack-merge ts-loader terser-webpack-plugin uglify-js
Enter fullscreen mode Exit fullscreen mode

Your package.json will look like this:

package.json

  • Create a webpack folder at root/project level and inside that add these 3 config files.

    1. webpack.common.js
    2. webpack.config.js
    3. webpack.dev.js
    4. webpack.prod.js
  • Create a src folder at root/project level and inside that add these 2 files.

    1. index.tsx
    2. index.html
  • Copy paste below code in index.tsx

import React from "react";
import { createRoot } from "react-dom/client";

const App = () => {
  return <div>Hello, React!</div>;
};

const rootElement = document.getElementById("root") as Element;
const root = createRoot(rootElement);

root.render(<App />);

Enter fullscreen mode Exit fullscreen mode
  • Copy paste below code in index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My React App</title>
</head>
<body>
  <div id="root"></div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Now lets update the webpack config files.

  • webpack.common.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: path.resolve(__dirname, "..", "./src/index.tsx"),
  output: {
    path: path.resolve(__dirname, "..", "dist"),
    filename: "bundle.js",
  },
  resolve: {
    extensions: [".ts", ".tsx", ".js"],
  },
  module: {
    rules: [
      {
        test: /\.(ts|js)x?$/,
        use: "ts-loader",
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "..", "./src/index.html"),
    }),
  ],
  devServer: {
    static: "./dist",
  },
};

Enter fullscreen mode Exit fullscreen mode
  • webpack.config.js
const { merge } = require("webpack-merge");
const commonConfig = require("./webpack.common");

module.exports = (envVars) => {
  const { env } = envVars;
  const envConfig = require(`./webpack.${env}.js`);
  const config = merge(commonConfig, envConfig);
  return config;
};

Enter fullscreen mode Exit fullscreen mode
  • webpack.dev.js
const webpack = require("webpack");

module.exports = {
  mode: "development",
  devtool: "cheap-module-source-map",
  devServer: {
    hot: true,
    open: true,
  },
  plugins: [
    new webpack.DefinePlugin({
      "process.env.name": JSON.stringify("development"),
    }),
  ],
};

Enter fullscreen mode Exit fullscreen mode
  • webpack.prod.js
const webpack = require("webpack");
const TerserPlugin = require("terser-webpack-plugin");

module.exports = {
  mode: "production",
  devtool: false,
  plugins: [
    new webpack.DefinePlugin({
      "process.env.name": JSON.stringify("production"),
    }),
  ],
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        minify: TerserPlugin.uglifyJsMinify,
        extractComments: true,
        parallel: true,
        test: /\.(ts|js)x?$/,
        terserOptions: {
          compress: {
            drop_console: true,
          },
          output: {
            comments: false,
          },
        },
      }),
    ],
  },
};
Enter fullscreen mode Exit fullscreen mode
  • Update/replace the scripts section in your package.json file:
"scripts": {
    "start": "webpack serve --config webpack/webpack.config.js --env env=dev",
    "build": "webpack --config webpack/webpack.config.js --env env=prod"
  }
Enter fullscreen mode Exit fullscreen mode

Setup TypeScript

At root/project level add tsconfig.json file and paste below config in it.

{
  "compilerOptions": {
    "target": "ES6",                                  
    "lib": [
      "DOM",
      "ESNext"
    ],                                        
    "jsx": "react-jsx",                               
    "module": "ESNext",                               
    "moduleResolution": "Node",                     
    "types": ["react", "react-dom", "@types/react", "@types/react-dom"],                                      
    "resolveJsonModule": true,                       
    "isolatedModules": true,                          
    "esModuleInterop": true,                            
    "forceConsistentCasingInFileNames": true,            
    "strict": true,                                      
    "skipLibCheck": true                                
  }
}

Enter fullscreen mode Exit fullscreen mode

Now your project folder and file structure will look like this:

Project Structure

Run the development server

In terminal/command prompt run below command to run your development server:

npm start
Enter fullscreen mode Exit fullscreen mode

Your React app should now be running at http://localhost:8080.

Set up ESLint and Prettier

  • Install ESLint, Prettier, and the necessary plugins:
npm install --save-dev eslint eslint-config-prettier eslint-plugin-prettier @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-plugin-react
Enter fullscreen mode Exit fullscreen mode
  • Create an .eslintrc.json file in the root of your project with the following configuration:
{
  "env": {
    "browser": true,
    "es2021": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/recommended",
    "prettier"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 12,
    "sourceType": "module"
  },
  "plugins": [
    "react",
    "@typescript-eslint",
    "prettier"
  ],
  "rules": {
    "prettier/prettier": "error"
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Create a .prettierrc file in the root of your project with the following configuration:
{
  "semi": true,
  "trailingComma": "all",
  "singleQuote": false,
  "printWidth": 100,
  "tabWidth": 2
}
Enter fullscreen mode Exit fullscreen mode
  • Update the scripts section in your package.json file:
"scripts": {
    "start": "webpack serve --config webpack/webpack.config.js --env env=dev",
    "build": "webpack --config webpack/webpack.config.js --env env=prod",
    "lint": "eslint . --ext .ts,.tsx --fix"
  }
Enter fullscreen mode Exit fullscreen mode
  • Run ESLint to check for any linting issues:
npm run lint
Enter fullscreen mode Exit fullscreen mode

Your final package.json will look like this:

Final package.json

Your final folder structure will look like this:

Final Folder Structure

Conclusion

By following this guide, you now have a production-ready React application setup with Webpack, TypeScript, ESLint and Prettier. This setup provides a solid foundation for building scalable and maintainable React applications with best practices in place.
Remember to keep your dependencies up-to-date and continue learning about these tools to optimize your development workflow further.
Happy coding!❤️

If you found this article useful, please share it with your friends and colleagues!

Read more articles on Dev.To ➡️ Shivam Pawar

Follow me on ⤵️
🌐 LinkedIn
🌐 Github

Top comments (17)

Collapse
 
tarunchakravarthy profile image
Tarun Duggempudi

That's a great step by step guide to get kick start project.

I would add little more details such as adding anchor links to the docs for terms like webpack, ESLint, and Prettier.

Furthermore, also write an additional notes if there is still a better way to achieve similar goal.

Finally, an effective article that helps to dive inn!

Collapse
 
shivampawar profile image
Shivam Pawar

Thanks @tarunchakravarthy for the feedback!

Collapse
 
litlyx profile image
Antonio | CEO at Litlyx.com

This is a great template for the newbies starting using react. Great job.

Antonio, CEO at Litlyx

Collapse
 
shivampawar profile image
Shivam Pawar

Thanks @litlyx

Collapse
 
flyingcrp profile image
flyingCrp

Great sharing,But why not just choose a mature scheme like vite?

Collapse
 
shivampawar profile image
Shivam Pawar

Thanks, webpack is highly configurable that’s why it is used in large enterprise applications

Collapse
 
viet_ho_398865447b7b14af8 profile image
Viet Ho

please fix tsconfig.js => tsconfig.json

Collapse
 
shivampawar profile image
Shivam Pawar

Thanks @viet_ho_398865447b7b14af8 for pointing out this mistake. I updated it.

Collapse
 
6qat profile image
Guilherme Ceschiatti B. Moreira

What advantages of this setup instead of Vite?

Collapse
 
shivampawar profile image
Shivam Pawar

Webpack is mainly known / used for large applications bundling with highly configurable things. Vite is emerging to be a better tool but still don’t provide much flexibility. If you want minimum and quick configuration for your app then definitely Vite is a better choice.

Collapse
 
mikhacavin profile image
Mikha Cavin

same question. @shivampawar

Collapse
 
lucianodecezare profile image
Luciano de Cezare

webpack.prod.js is equal to webpack.dev.js. Wasn't production supposed to be more optimized?

Collapse
 
shivampawar profile image
Shivam Pawar

Thanks @lucianodecezare for identifying my mistake. I accidentally pasted same config as dev. Updated webpack.prod.js with more configuration.

Collapse
 
brense profile image
Rense Bakker

Or: npm create vite@latest my-react-app -- --template react-ts

Collapse
 
umesh_fanmania_a970e8cff profile image
Umesh Fan Mania

I am one strong headed person, i’m the type of person that likes to see before believing, i and i learnt the hard way.What I am trying to say is my journey of investing in a wrong bitcoin platform even after warnings from my mom not to do so, I still went ahead to invest, that was how i lost a whopping sum of 350,000$, whoa!  I was almost dead, words can not describe how I felt when I realised my money had gone to those rippers.But one thing i have come to understand, whatever has a fake must also have an original, even though not everyone that claimed they recovered their bitcoin actually got their coins back,yet some might actually be telling the truth  and i am one of those that is telling the truth,because I was also a critic of bitcoin Recovery until i experience it first hand. It’s a long story but after searching for ways to recover my stolen bitcoin it was a dead end . By October I was referred to one  of the best of best. Here is their email address just in case you find yourself in my situation. Hacking hackerrone90  Gmail Dot Com. 
Highly Recommended!!

Collapse
 
kali_123 profile image
kali deb • Edited

it doesn't explain anything on how this optimizes your react app, It just shows us how to install npm packages

Collapse
 
shivampawar profile image
Shivam Pawar

Installing npm package is not a big deal.
If you read this article properly then you will see webpack configuration other than just npm installation commands, I used plugins to minify production bundle size. Also, by using eslint you make sure that developer will write quality code.

It takes time and efforts to write a detailed post. So please don’t just directly say that it’s just a npm package installation steps.