I wanted to setup react with webpack, babel, and typescript myself since I would like to know more and have a consistent boilerplate for development.
I have been trying to setup fast refreshing and hot reloading in react with `webpack5 following the documentation for react-refresh-webpack-plugin. I was not getting anywhere and decided to make a minimal example that reproduces the error.
My expectation is that I should be able to make changes to my source folder and the should appear immediately or at least upon refresh. As of now, neither happens.
I made sure to follow the primary readme for react-refresh-webpack-plugin as best I could. I will review it again and see what changes I can make according to it and report back here.
The file tree so far looks like :
├── babel.config.js
├── package-lock.json
├── package.json
├── src
│ ├── app.tsx
│ ├── index.html
│ └── index.tsx
├── tsconfig.json
└── webpack.config.js
my webpack config
// webpack.config.js
const path = require( 'path' )
const ReactRefreshPlugin = require( '@pmmmwh/react-refresh-webpack-plugin' )
const HTMLWebpackPlugin = require( 'html-webpack-plugin' )
// Ingredients
// Just to make things less ugly
const SRC = path.join( __dirname, 'src' )
const NODE_MODULES = /node_modules/
const MODE = 'development'
const INDEX = path.join( SRC, 'index.html' )
const ENTRY_POINT = path.join( SRC, 'index.tsx' )
// Objects nested within exports.
// Also to make things less ugly.
const PLUGINS = [
new ReactRefreshPlugin(),
new HTMLWebpackPlugin({
template : INDEX,
filname : './index.html'
})
]
const RESOLVE = { extensions : [
'.ts',
'.js',
'.tsx',
'.jsx'
]}
const RULES = [
// Babel
{
test : /\.tsx?$/,
exclude : NODE_MODULES,
include : SRC,
use : 'babel-loader'
}
]
// Prettier exports.
module.exports = ( env ) => {
const config = {
mode : MODE,
entry : ENTRY_POINT,
module : {
rules : RULES
},
plugins : PLUGINS,
resolve : RESOLVE
}
console.log( JSON.stringify( config, null, space = "\n" ) )
return config
}
and my babel config
// babel.config.js
// Variables
const PRODUCTION = 'production'
// Methods
const PRESETS = ( api ) => [
'@babel/preset-env',
'@babel/preset-typescript',
[
'@babel/preset-react',
{
development : !api.env( PRODUCTION ),
runtime : 'automatic'
}
]
]
const PLUGINS = ( api ) => [
api.env( PRODUCTION ) && 'react-refresh/babel'
].filter( Boolean )
module.exports = ( api ) => {
api.cache.using(
() => process.env.NODE_ENV
)
return {
presets : PRESETS( api ),
plugins : PLUGINS( api )
}
}
package.json:
{
"name": "typescript-react-with-refresh",
"version": "1.0.0",
"description": "Trying to get hot reloading working with webpack5.",
"main": "index.js",
"scripts": {
"start": "webpack serve --hot",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.16.7",
"@babel/preset-env": "^7.16.7",
"@babel/preset-react": "^7.16.7",
"@babel/preset-typescript": "^7.16.7",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.4",
"@types/react": "^17.0.38",
"@types/react-dom": "^17.0.11",
"babel-loader": "^8.2.3",
"html-webpack-plugin": "^5.5.0",
"react-refresh": "^0.11.0",
"typescript": "^4.5.4",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.7.2"
},
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
}
}
and finally the configuration for the typescript compiler:
// tsconfig.json
{
"compilerOptions": {
"jsx": "react-jsx",
"lib": ["dom", "dom.iterable", "esnext"],
"module": "ESNext",
"moduleResolution": "node",
"outDir": "dist",
"target": "ESNext",
"sourceMap": true
},
"include": ["src"]
}
Finally, if index.html or any other source files are required, I can provide those. For now I am not providing them to keep this post brief. Thank you in advance for any help!
Update
I found that I should have installed ts-node and type-fest as dev dependencies, and change webpack.config.js to webpack.config.ts. Nonetheless the problem persists.