Programster's Blog

Tutorials focusing on Linux, programming, and open-source

Integrate Webpack Into Typescript/React Application

Previously, we set up a Typescript + React project. This tutorial will take it further by integrating Webpack to bundle it all up and serve it in our browser.

Steps

First, we’re going to install Webpack locally, as recommended by the official Webpack documentation.

npm install webpack --save-dev \
  && npm install webpack-cli --save-dev \
  && npm install webpack-dev-server --save-dev \
  && npm install awesome-typescript-loader --save-dev \
  && npm install html-webpack-plugin --save-dev

We’ve now installed Webpack with four additional dev Dependencies.

Let’s go ahead and create our webpack.config.js file in the root of our project.

const path = require('path');
const HtmlWebPackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        app: ['./src/App.ts'],
        vendor: ['react', 'react-dom']
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'js/[name].bundle.js'
    },
    devtool: "source-map",
    resolve: {
        extensions: [".ts", ".tsx", ".js", ".jsx", ".json"]
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: "awesome-typescript-loader"
            }
        ]
    },

    plugins: [
        new HtmlWebPackPlugin({
            template: "./src/index.html"
        })
    ]
};

Things to note:

  • Our entry object contains a path to App.ts file we made earlier.
  • It also includes a vendor array, React and React-Dom are our only libraries, so we add these here. If you want to add additional libraries, you should add them to this so Webpack knows about it.
  • Our output object tells webpack where to bundle our app, which in this case is our dist folder.
  • Under module we’ve added our awesome-type-script-loader.
  • Under our plugin array, we’ve added our source index.html file using the HtmlWebPackPlugin. A minified html file will get placed in our dist folder along with the reference to our bundled up js files.

Next, create a new index.html file and add it to our src folder. Make sure there is <div id="app"></div> in yours. This is where our React app will look to render to.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>App</title>
</head>

<body>
    <div id="app"></div>
</body>

</html>

Open App.ts and add to the very bottom of the file new App();

export class App
{
    constructor()
    {
        console.log("Hello app!");
    }
}

new App();

Now in the root folder of the project, run in the terminal.

node_modules/.bin/webpack-dev-server  --mode development

You should now have a successful build, with a webserver at http://localhost:8080/.

Inspecting the dev console (F12 > console), you should also see our log in the console outputting “Hello app!”

Making It More React

Now that we have React, TypeScript and Webpack all playing nicely, let’s actually get some React rendering.

Create a Main.tsx file and paste in the below.

import * as React from 'react';
import { App } from './App';

export interface IMainProps
{
    app: App; // Reference to our App.ts class
}

export class Main extends React.Component<IMainProps, {}>
{
    constructor(props: IMainProps)
    {
        super(props);
    }

    public render(): JSX.Element
    {
        return (
            <>
                Main app
            </>
        );
    }
}

Open App.ts file and paste in the below.

import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { Main } from './Main';

export class App
{
    constructor()
    {
        this.render();
    }

    private render(): void
    {
        ReactDOM.render(React.createElement(Main, { app: this }), document.getElementById("app"));
    }
}

new App();

Things to note here:

  • We’re rendering our Main.tsx class as our main React UI.
  • We’re passing in a reference to our App class as a react prop. There might be stuff we want to do or access in our App class at a later date.
  • We’re passing in our app id element we added to our index.html file earlier. This will be where React will render.

Now if we go back to our browser, we should see “Main app” on our page. Your browser should have auto-reloaded since we changed some code. React has now landed on our webpage.

Tidying Up and Publishing

Typing in ./node_modules/.bin/webpack-dev-server --mode development just to run the dev server everytime isn’t great. We can change this into a more friendly node command.

Open up our package.json file and update the scripts object so it looks like below:

{
    "scripts": {
        "dev": "webpack-dev-server --mode development",
        "build": "webpack --mode production"
    }
}

We can now run our above commands in the terminal:

  • Running npm run dev is now doing what we were typing earlier: ./node_modules/.bin/webpack-dev-server --mode development
  • Running npm run build will tell webpack to compile our app for production. It will essentially minify everything and bundle it into our dist folder, ready to upload to the web.
Last updated: 24th May 2019
First published: 18th May 2019