Building a TypeScript-React Project from Scratch with Webpack
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 topreserve
, 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!