We’ll build a counter app to show hot module reloading while maintaining state using webpack-dev-server or express to update the modules
React Hot Loader with Web Dev Server
Create Project
proj/
├─ dist/
├─ .babelrc
├─ package.json
├─ webpack.config.js
└─ src/
└─ assets/
└─ index.html
└─ css/
└─ js/
└─ img/
└─ fonts/
└─ components/
└─ pages/
└─ services/
└─ App.js
└─ index.js
Initialise Project Folder
npm init -y
Install Development Dependencies
npm i -D \
webpack-dev-server \
webpack \
webpack-cli \
babel-loader \
@babel/core \
@babel/preset-env \
@babel/preset-react \
html-webpack-plugin
Include .babelrc file to configure babel compilation for this project
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
Install Application Dependencies
npm i -S react react-dom react-hot-loader
Create src/assets/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="/css/main.css">
</head>
<body>
<div id="root"></div>
</body>
</html>
Create the react application with react-hot-loader
import { hot } from 'react-hot-loader/root';
import React from 'react';
const App = () => {
const [counter, setCounter] = React.useState(0)
const [data, setData] = React.useState([])
async function getData() {
let res = await fetch("https://jsonplaceholder.typicode.com/todos");
let jsonData = await res.json();
setData(jsonData)
}
function increment() {
setCounter(counter + 1)
}
return (
<>
<div>{`Awesome Counter: ${counter}`}</div>
<button onClick={increment}>Increment Now</button>
<button onClick={getData}>Get API Data</button>
<table border={1}>
<thead>
<tr>
<th>UserId</th>
<th>Id</th>
<th>Title</th>
<th>Completed</th>
</tr>
</thead>
<tbody>
{data.map((item, i) => {
return (
<tr key={i}>
<td>{item.userId}</td>
<td>{item.id}</td>
<td>{item.title}</td>
<td>{item.completed}</td>
</tr>
)
})}
</tbody>
</table>
</>
);
}
export default hot(App);
import React from "react";
import { render } from "react-dom";
import App from './App'
render(<App />, document.getElementById("root"));
Configure webpack through a webpack.config.js file
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyPlugin = require("copy-webpack-plugin");
const webpack = require("webpack");
const path = require("path");
module.exports = {
devtool: "source-map",
mode: "development",
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json']
},
module: {
rules: [
{
test: /\.(js)x?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
},
},
{
test: /\.(ts)x?$/,
exclude: /node_modules/,
use: {
loader: 'ts-loader'
},
},
{
// Preprocess your sass and scss files
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
'sass-loader',
],
},
{
// Preprocess your css files
test: /\.css$/,
exclude: /node_modules/,
use: [
'style-loader',
'css-loader'
],
}
]
},
devServer: {
port: 4000,
open: true,
compress: true, //Enable gzip compression for everything served
historyApiFallback: true, //fallback to index.html in the event that a requested resource cannot be found.
hot: true //Enable webpack's Hot Module Replacement feature
},
output: {
filename: "js/main.[hash].js",
publicPath: "/"
},
plugins: [
new HtmlWebpackPlugin({
title: "WebDevServer",
filename: 'index.html',
template: 'src/assets/index.html'
}),
new CopyPlugin({
patterns: [
{ from: 'src/assets', to: '.' }
],
}),
]
};
Add a “dev” and “build” script to the package.json
...
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack"
},
...
When you run "npm run dev", webpack writes the project to memory and any further updates are pushed to memory without losing state.
When you run "npm run build", webpack compiles and writes the project to disk under the “dist” folder.
Top comments (0)