# Using Webpack to build React Application

{% code title="webpack.config.js" %}

```javascript
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require("webpack")
const port = process.env.PORT || 3000;
module.exports = {
    mode:  "development",
    devtool:"source-map",
    entry:{
        main: "./src/index.tsx",
    },
    output:{
        filename:'[name].js',
        path:__dirname +"/dist",
    },
    resolve:{
        alias: {
          "react-dom": "@hot-loader/react-dom",
        },
        extensions:[".ts",".tsx",".js",".scss",".css"],
        modules: [ "node_modules"]
    },
    //  add the additional function to webpack
    plugins:[
      // enable hot reload
      new webpack.HotModuleReplacementPlugin() ,
      // separate css file from js file when building
      new MiniCssExtractPlugin({filename:"[name].css"}),
      // generate html file with output script 
      new HtmlWebpackPlugin({
        template: "public/index.html",
        favicon: "public/favicon.ico"
      })
    ],
    //  the default only handle js file, so need to add loader to process the 
    //  dependency
    module:{
        rules:[
          //  compile tsx to js and then to browser compatible language 
          //  through babel
          {
            test: /\.tsx?$/,
            use: ["babel-loader" , {
              loader: "ts-loader",
              options: {
                configFile: "tsconfig.json",
              },
            }],
            exclude: /node_modules/,
          },
          //  compile scss to css and then build to separate css file
          {
            test: /\.scss$/i,
            use: [
              MiniCssExtractPlugin.loader,
              {
                loader: "css-loader",
                options: {
                  modules: true,
                },
              },
              "sass-loader"
            ],
          }
        ]
    },
    // maintain dev server for local env
    devServer:{
      host: "localhost",
      port : port,
      historyApiFallback: true,
      open: true,
      hot:true
    }
}
```

{% endcode %}

{% code title=".babelrc" %}

```json
// to compile language to browser-compatible language
{
    "presets": ["@babel/preset-env", "@babel/preset-react"],
    "plugins": [
        "@babel/plugin-syntax-dynamic-import",
        "react-hot-loader/babel"
    ]
}
```

{% endcode %}

{% code title="package.json" %}

```json
  "name": "webpack-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack-dev-server",
    "build": "webpack --config webpack.config.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@hot-loader/react-dom": "^17.0.2",
    "@types/react": "^18.0.14",
    "@types/react-dom": "^18.0.5",
    "css-loader": "^6.6.0",
    "html-webpack-plugin": "^5.5.0",
    "mini-css-extract-plugin": "^2.5.3",
    "react-hot-loader": "^4.13.0",
    "sass-loader": "^12.6.0",
    "style-loader": "^3.3.1",
    "ts-loader": "^9.2.6",
    "typescipt": "^1.0.0",
    "typescript": "^4.5.5",
    "typescript-plugin-css-modules": "^3.4.0",
    "webpack": "^5.69.1",
    "webpack-cli": "^4.9.2"
  },
  "dependencies": {
    "@babel/core": "^7.18.6",
    "@babel/plugin-proposal-class-properties": "^7.18.6",
    "@babel/plugin-syntax-dynamic-import": "^7.8.3",
    "@babel/preset-env": "^7.18.6",
    "@babel/preset-react": "^7.18.6",
    "babel-loader": "^8.2.5",
    "node-sass": "^7.0.1",
    "prop-types": "^15.8.1",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0",
    "sass": "^1.49.9",
    "webpack-dev-server": "^4.9.3"
  }
}
```

{% endcode %}

{% code title="tsconfig.json" %}

```json
{
    "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,
      "jsx": "react-jsx",
      "baseUrl": "src",
    },
    "include": [
      "**/*.ts",
      "**/*.tsx"
    ]
  }
```

{% endcode %}

{% embed url="<https://github.com/headshootcheng/webpack-test>" %}
