Andrew
Web development enthusiast with a keen interest in anything frontend.
Quick start-up guide on how to put together a basic development environment for a React application written in TypeScript and build with Webpack.
While there are really good out of the box
kits out there that will get you up and running with React and Typescript (eg: create-react-app with react-scripts-ts) I feel that you can miss out on what is actually going on under the hood. This guide will hopefully give you a better idea of how you can set up your own project with the core tools and utilities - giving you more control over what you include and how you configure it for your project.
The basic structure of the project looks like this. Refer to this when files are mentioned below. Feel free to create the directories now.
.
├── dist
│ ├── bundle.js
│ └── index.html
├── package.json
├── package-lock.json
├── src
│ └── index.tsx
├── tsconfig.json
└── webpack.config.js
npm i webpack webpack-cli --save-dev
npm i react react-dom --save-dev
Next we create a basic webpack.config.js
file in the project root directory. Here we will set mode: 'development'
(we will come back to this later)
const path = require('path');
module.exports = {
mode: 'development',
entry: './src/index.tsx',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
We set the entry point to index.tsx
this will be the root of the React TypeScript application and is the first thing Webpack will process when building dependencies.
npm i typescript --save-dev
Now that TypeScript compiler is installed we need to create some basic config in the project root directory.
{
"compilerOptions": {
"sourceMap": true,
"jsx": "react" //we need this for react
}
}
We will be using Webpack as our build tool so we need to tell it to use TypeScript. For this we will use ts-loader
, install
npm i ts-loader --save-dev
and configure by adding the following to your webpack.config.js
,
resolve: {
extensions: [".ts", ".tsx", ".js"]
},
module: {
rules: [
{ test: /\.tsx?$/, loader: "ts-loader" }
]
}
The resolve
section is telling Webpack to process any .ts
,tsx
or js
files while within the module
section we have a rule that will tell Webpack to use ts-loader
for any .ts
or .tsx
files via a regular expression.
Configure build script - add the following to package.json
"scripts": {
"build": "webpack"
},
Before we build our application we need to create a test index.tsx
file. Let's start with:
import * as React from 'react'
import * as ReactDOM from 'react-dom'
ReactDOM.render(
<div>It's alive!</div>,
document.getElementById('root') as HTMLElement
)
We should also create a basic index.html
file to display our page. Put this in the dist
directory
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>Webpack React Typescript app</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<script src="bundle.js"></script>
<div id="root"></div>
</body>
</html>
We should now be able to build our index.tsx
with the power of Webpack + TypeScript by running npm run build
. You should get output similar to the below:
Hash: 6d4f525587bc81d87a3d
Version: webpack 4.8.3
Time: 6605ms
Built at: 2018-05-25 18:30:48
Asset Size Chunks Chunk Names
bundle.js 705 KiB main [emitted] main
Entrypoint main = bundle.js
[./src/index.tsx] 200 bytes {main} [built]
+ 21 hidden modules
We need to serve the webpage to actually see it. To do this we will use webpack-dev-server
which also provides live reloading - any changes that are made will trigger a rebuild and a refresh of the page.
npm i webpack-dev-server --save-dev
This will link in with the webpack-cli
and serve the output. Let's set it as the start
script by adding the following to the scripts
section of package.json
:
"start": "webpack-dev-server",
We need to configure webpack-dev-server
to point at the dist
directory. Add this to your webpack.config.js
devServer: {
contentBase: path.resolve(__dirname, "dist"),
}
Now just run npm start
and it should open a page in your default browser - you should now see It's alive!
printed.
That is about it for getting a basic development environment set up. One last thing that we should do is separate development vs production configuration for Webpack. This is done by having 3 Webpack config files instead of one: webpack.common.js
, webpack.dev.js
and webpack.prod.js
. Shared config goes in common
while dev and prod are for development and production respectively.
There is a nice tool called webpack-merge
that we will need to install that will allow Webpack to combine (or 'merge') the common configuration into the environment specific config.
npm i webpack-merge --save-dev
We can now remove webpack.config.js
and replace with the following
webpack.dev.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const path = require('path');
module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
contentBase: path.resolve(__dirname, "dist")
}
});
webpack.common.js
const path = require('path');
module.exports = {
entry: './src/index.tsx',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
resolve: {
extensions: [".ts", ".tsx", ".js"]
},
module: {
rules: [
{ test: /\.tsx?$/, loader: "ts-loader" }
]
},
};
webpack.prod.js
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const path = require('path');
module.exports = merge(common, {
mode: 'production',
});
All we need to do now is update the package.json
NPM scripts to have webpack-cli
point to the updated config:
"scripts": {
"start": "webpack-dev-server --open --config webpack.dev.js",
"build": "webpack --config webpack.prod.js",
}
That should be it, you can now develop and build your application. This is just the start though, there are many more config options you can tweak. Take a look at the Webpack Configuration documentation
Web development enthusiast with a keen interest in anything frontend.