Setup a React App using Webpack, Babel and TypeScript
Tags: react, webpack, babel, typescript
Published: 2021-03-05 14:31:34

This article is part of a two part series on how to configure a React app from scratch with Webpack and Babel and eventually add TypeScript to it. To read the first article in this series, click on the below link.

   * [Setup a React app with Webpack and Babel](https://dev.to/deadwing7x/setup-a-react-app-with-webpack-and-babel-4o3k) 

***

#### So you stumbled upon [TypeScript](https://www.typescriptlang.org/) and loved how you will be able to add type safety along with a whole bunch of other things that it has to offer. So, let's modify last week's app and add TypeScript to it. In case you haven't read last week's article on how to setup a react app with webpack and babel, feel free to go through the below link and setup a basic react app to which we can add TypeScript.


**To get the starter code click on this below link.**

Link to the GitHub repo: [react-with-webpack](https://github.com/deadwing7x/react-with-webpack)

***

#### Let's start with the required steps now.

1. Install the following packages **typescript**, 
**@types/react** and **@types/react-dom** using the following command. 

    You can also replace the *--save-dev* with a more subtle *-D* to install any package as a dev dependency.

    ```
    npm install typescript

    npm install @types/react @types/react-dom --save-dev
    ```

    **@types/react:** contains type definations for React.

    **@types/react-dom:** contains type definations for React DOM.

2. We will need to let Babel know that we are including typescript in the project. So, let's go ahead and install the package **@babel/preset-typescript** as a dev dependency.

    ```
    npm install @babel/preset-typescript --save-dev
    ```

3. Now we have a mean to let Babel know of the typescript files that we will be using. But we still need to load these files with webpack, right? For that we need another package named as **ts-loader**.

    ```
    npm install -D ts-loader
    ```
    
    Your **package.json** file should look something like this.

    <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1614875520420/ugOzSsHPE.png" alt="package.json" />

4. We have all the required packages now. It's time to make some changes in our *webpack.config.js* and *.babelrc* file.

    Replace the below code with the one present in your **.babelrc** file.

    ```
    {
        "presets": [
            "@babel/env",
            "@babel/react",
            "@babel/preset-typescript"
        ],
        "plugins": [
            "@babel/plugin-proposal-class-properties"
        ]
    }
    ```

    As you can see, we are adding a new preset which is the *@babel/preset-typescript* to our already existing set of presets.

    Time to make changes to our **webpack.config.js** file now. Copy the below code and replace the existing code which is present in the file.

    ```
    const path = require("path");
    const HtmlWebpackPlugin = require("html-webpack-plugin");

    module.exports = {
        entry: "./src/index.tsx",
        output: { path: path.join(__dirname, "build"), filename: "index.bundle.js" },
        mode: process.env.NODE_ENV || "development",
        resolve: {
            extensions: [".tsx", ".ts", ".js"],
        },
        devServer: { contentBase: path.join(__dirname, "src") },
        module: {
            rules: [
                {
                    test: /\.(js|jsx)$/,
                    exclude: /node_modules/,
                    use: ["babel-loader"],
                },
                {
                    test: /\.(ts|tsx)$/,
                    exclude: /node_modules/,
                    use: ["ts-loader"],
                },
                {
                    test: /\.(css|scss)$/,
                    use: ["style-loader", "css-loader"],
                },
                {
                    test: /\.(jpg|jpeg|png|gif|mp3|svg)$/,
                    use: ["file-loader"],
                },
            ],
        },
        plugins: [
            new HtmlWebpackPlugin({
                template: path.join(__dirname, "src", "index.html"),
            }),
        ],
    };
    ```

5. Time to use TypeScript. But wait, we need something to specify that this directory is a TypeScript project, right! We also need to provide the compiler options in which our TypeScript files will be compiled. For that we will need a new file named as **tsconfig.json**.

    Let's go ahead and create that file.

    ```
    touch tsconfig.json
    ```

    For now, remove the existing code from the **tsconfig.json** file and replace it with the below code.

    ```
    {
        "compilerOptions": {
            "target": "es5",
            "lib": [
                "dom",
                "dom.iterable",
                "esnext"
            ],
            "allowJs": true,
            "skipLibCheck": true,
            "esModuleInterop": true,
            "allowSyntheticDefaultImports": true,
            "strict": true,
            "forceConsistentCasingInFileNames": true,
            "noFallthroughCasesInSwitch": true,
            "module": "esnext",
            "moduleResolution": "node",
            "resolveJsonModule": true,
            "isolatedModules": true,
            "noEmit": false,
            "jsx": "react-jsx"
        },
        "include": [
            "src"
        ]
    }
    ```

    Let's go over the attributes now.

    **"target": "es5" =>** will compile es6 or above code to es5 so that it is compatible with browsers.

    **"include": [src]" =>** specifies that only the files in the *src* folder should be included.

    **"sourceMap": true =>** Generates corresponding ‘.map’ file so that it can be used in the production code for debugging.
    
    **"strict": true =>** enables a wide range of type checking behavior that results in stronger guarantees of program correctness.
    
    **"allowJs": true =>** allows JavaScript files to be imported inside your project, instead of just .ts and .tsx files.

    To learn more about the various attributes used in the file visit this [link](https://www.typescriptlang.org/tsconfig).

6. Last but not the least, its time to rename our JavaScript files (**.js**) to TypeScript - React (**.tsx**).

      <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1614876953079/38HnYETS7.png" alt="react-with-typescript" />

     *renamed index.js & App.js to index.tsx & App.tsx respectively*

7. Go ahead and run the below command to start the app.

    ```
    npm run start
    ```

    The app will be served at **http://localhost:8080**.

Well, you have successfully added TypeScript to your project. Go ahead and make use of its functionalities to build great webapps.

Have a great day. Thanks for reading the entire thing.

Here's the link to the [Github Repo](https://github.com/deadwing7x/react-with-webpack-typescript) in case you have faced some issue during the entire process. Feel free to make some tweaks if you find something breaking because of updates to any of the packages.

<span>Cover Photo by <a href="https://unsplash.com/@cristina_gottardi?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Cristina G