Building a TypeScript-React Project from Scratch with Webpack

Rishabh
JavaScript Journal: Unlocking Project Potential
3 min readOct 13, 2023

Webpack is the go-to bundler for many JavaScript projects, offering robust and flexible configurations. While Create React App (CRA) provides a more straightforward setup, configuring Webpack manually grants you greater control over your project. This blog post walks you through setting up a React-TypeScript project from the ground up using Webpack.

Initial Project Setup

Initialise a new Node.js project and navigate into it:

mkdir my-ts-react-webpack-app
cd my-ts-react-webpack-app
npm init -y

Installing Core Dependencies

Install React and ReactDOM:

npm install --save react react-dom

And TypeScript:

npm install --save-dev typescript

TypeScript Configuration

Create a tsconfig.json file for TypeScript settings:

{
"compilerOptions": {
"target": "es5",
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"outDir": "./dist",
"strict": true,
"esModuleInterop": true
},
"include": ["src/**/*"]
}

What is “jsx” in tsconfig, and what are the other options?

The jsx flag in tsconfig.json specifies how JSX code should be transformed. Setting it to "react" means that TypeScript will convert JSX into React.createElement() calls, which is what you'd want for a typical React project. Other options include:

  • "preserve": Keeps the JSX as is, later to be transformed by another (possibly Babel) transform step.
  • "react-native": Used for React Native projects. Similar to preserve, but the output will have a .js file extension.

Webpack Configuration

Install Webpack dependencies:

npm install --save-dev webpack webpack-cli webpack-dev-server

Basic Webpack Config

Create a webpack.config.js at your project's root:

const path = require('path');

module.exports = {
entry: './src/index.tsx',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
}
};

Babel Setup

Install Babel and presets:

npm install --save-dev @babel/core babel-loader @babel/preset-env @babel/preset-react @babel/preset-typescript

Babel Config

Create a .babelrc file:

{
"presets": [
"@babel/preset-env",
"@babel/preset-react",
"@babel/preset-typescript"
]
}

What are presets in Babel?

Babel presets are collections of plugins that are used for transformations. Instead of setting each plugin individually, a preset bundles specific plugins to perform a particular transformation. In this case, @babel/preset-env is for converting modern ECMAScript code, @babel/preset-react is for JSX and other React-related transformations, and @babel/preset-typescript is for TypeScript support.

Integrating Babel with Webpack

Update webpack.config.js to include Babel:

// Existing Code
module.exports = {
// ...
module: {
rules: [
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
}
};

HTML Template

Create ./src/index.html file and paste below content

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Webpack React TS</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

Install html-webpack-plugin:

npm install --save-dev html-webpack-plugin

Update webpack.config.js:

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
// Existing Code
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
};

Why use html-webpack-plugin?

The html-webpack-plugin generates an HTML file, injects the bundled JavaScript, and writes this file to the dist directory. This automates creating HTML files to serve your Webpack bundles, which is particularly useful for getting all your JavaScript files and linking them to your HTML.

Sample TypeScript-React Component

Create a src/index.tsx file:

import React from 'react';
import ReactDOM from 'react-dom/client';

const App: React.FC = () => {
return <div>Hello, world!</div>;
};

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(<App />);

Running the Project

In package.json, add:

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

Run npm start and visit http://localhost:8080/.

Why did you use the script “build”: “webpack — mode production”?

The "build": "webpack --mode production" script is aimed to prepare your app for deployment. When Webpack runs in production mode, it performs additional optimisations to your code, like minification and dead code elimination, thus making the code more efficient and the bundle size smaller. Using --mode production tells Webpack to use its built-in optimisations for production.

Conclusion

You've successfully set up a TypeScript-React project using Webpack! This setup allows you to use TypeScript and comprehensively understand your project's build system.

Happy Coding!

--

--

Rishabh
JavaScript Journal: Unlocking Project Potential

👋 React wizard by day, guitar hero by night. I write code that even my bugs get applause! On a quest to make UI/UX spell "U I'm Excited!" 🎸🤓