Webpack 4 + React with Typescript

Posted on September 17, 2018 - 12 min read

Webpack


Webpack is a static module bundler for Javascript applications. It takes modules(either installed or custom) and generates static assets to represent those modules.


And we are going to set up our own Webpack configuration to React with Typescript.


As stated in the documentation getting started is quite easy, as you only need to understand its core concepts - Entry, Output, Loaders, and plugins.


Entry: The entry point such as /src/index.js which is the default for Webpack 4 is what Webpack will use to start building out/resolving its dependencies.


Output: The output property such as ./dist (default for Webpack 4) tells Webpack where to output the bundles it creates and how to name them.


Loaders: Since Webpack only understands native Javascript code, these loaders enable it to process different types of imported files and convert them into valid modules when it encounters a specific type of file. Loaders have 2 properties in the configuration file


  • The test property which identifies which file or files should be transformed

  • The use property which indicates which loader can be used to do the transforming

Plugins: This allows you to extend Webpack capabilities to perform a wider range of tasks like bundle optimization, asset management and injection of environment variables. You can check out some of the plugins provided by Webpack here


Installing Webpack:


To get started, initialize your newly created project folder npm init -y


Install webpack and webpack cli as dev dependencies


# yarn
yarn add webpack webpack-cli -D

# npm
npm i webpack webpack-cli -D

Configuring Webpack:


Let's create a Webpack config file webpack.config.js in the root of our project folder and add the following to it:


const path = require('path');
module.exports = {
entry: './src/index.tsx',
output: {
path: path.join(__dirname, '/dist'),
filename: 'bundle.min.js'
}
}
view raw webpack.config.js hosted with ❤ by GitHub


  • In the above snippet, we specified src/index.tsx as the entry point

We told Webpack to output the bundle into the dist folder with the name bundle.min.js


Adding Typescript:


Install Typescript's dependencies


# yarn
yarn add typescript awesome-typescript-loader -D

# npm
npm i typescript awesome-typescript-loader -D

We need to add compilation settings for our Typescript so let's go ahead and create a tsconfig.json in the root of our project folder and add the following to it:


{
"compilerOptions": {
"sourceMap": true,
"noImplicitAny": false,
"module": "commonjs",
"target": "es6",
"lib": [
"es2015",
"es2017",
"dom"
],
"removeComments": true,
"allowSyntheticDefaultImports": false,
"jsx": "react",
"allowJs": true,
"baseUrl": "./",
"paths": {
"components/*": [
"src/components/*"
],
}
}
}
view raw tsconfig.json hosted with ❤ by GitHub


Add Typescript configuration to Webpack:


const path = require('path');
module.exports = {
entry: './src/index.tsx',
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
output: {
path: path.join(__dirname, '/dist'),
filename: 'bundle.min.js'
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'awesome-typescript-loader'
}
]
}
}
view raw webpack.config.js hosted with ❤ by GitHub


Here we are telling Webpack to:


  • Resolve file extensions with .tsx, .ts and .js
  • All files with the extension .tsx or .ts should be processed by awesome-typescript-loader

Adding React:


Since we are using Typescript we need to add React and React Dom along with their type declaration


# yarn
yarn add react react-dom @types/react @types/react-dom

# npm
npm i react react-dom @types/react @types/react-dom

Before we go ahead to add our example file let's modify our package.json to have a start script to run Webpack


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

You can enable Webpack's built-in optimization that corresponds to each environment by setting the mode to either development, production or none.


Note: The default value is production


Before we create our React component let's create a simple interface file that would be used by this component. In the src folder create a PageInterface.ts file and add the following to it:


export default interface Page {
color: string;
}
view raw pageInterface.ts hosted with ❤ by GitHub


Now, let’s create a simple React component App.tsx in the src/components folder:


import * as React from 'react';
import PageInterface from '../PageInterface';
class App extends React.Component<PageInterface, {}> {
render() {
return (<div>
<h1>Welcome to React with Typescript</h1>
<p>The color of this page is: {this.props.color}</p>
</div>
);
}
}
export default App;
view raw App.tsx hosted with ❤ by GitHub


The index.tsx file will now contain:


import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './components/App';
ReactDOM.render (
<App color="Blue" />,
document.getElementById("root")
);
view raw index.tsx hosted with ❤ by GitHub


Adding HTML:


For this, we need to use a Webpack plugin html-webpack-plugin which helps simplifies the creation of HTML files to help serve our Webpack bundles


# yarn
yarn add html-webpack-plugin -D
# npm
npm i html-webpack-plugin -D

Update the Webpack config file:


const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.tsx',
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
output: {
path: path.join(__dirname, '/dist'),
filename: 'bundle.min.js'
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'awesome-typescript-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
}
view raw webpack.config.js hosted with ❤ by GitHub


Now, let’s create the index.html template in the src folder:


<!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>TypeScript + React</title>
</head>
<body>
<div id="root">
</div>
</body>
</html>
view raw index.html hosted with ❤ by GitHub


Running yarn start or npm start will now create the dist folder with our bundled Javascript files and an HTML file with a script tag inside the body


Development Server:


Finally, we are going to set up a development server using the webpack-dev-server which will open up a default browser when we do npm start and also provide us with live reloading on the fly


# yarn
yarn add webpack-dev-server --D

# npm
npm i webpack-dev-server --D

Update our package.json


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

Here we are telling Webpack to run on development mode while watching for changes, using the --hot option to enable Webpack’s HMR(Hot Module Replacement) and then --open to open up a default browser.


Running yarn start or npm start now will open up the default web browser on localhost:8080


Webpack, Typescrit, React starter


Conclusion:


This is just a basic way of setting up Webpack with React and Typescript a lot can still be done here by adding more loaders and plugins but I hope this has been able to get you started.


As always, Thank you for reading!


Photo Credit



My Life As A Software Engineer BlogI Learn, I Share, We Grow.