How to bundle a React app with Webpack
Bundling React applications with Webpack provides full control over the build process, optimization strategies, and asset handling. With over 12 years of React experience since 2014 and as the creator of CoreUI, I’ve configured Webpack for numerous production React applications. Webpack bundles JavaScript, CSS, images, and other assets into optimized files for deployment with extensive plugin ecosystem. This approach offers maximum flexibility for complex build requirements and custom optimization strategies.
Configure Webpack with babel-loader, CSS loaders, and optimization plugins to bundle React applications for production.
Basic Webpack configuration:
// webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js',
clean: true
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react']
}
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource'
}
]
},
resolve: {
extensions: ['.js', '.jsx']
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html'
})
]
}
Production configuration:
// webpack.prod.js
const { merge } = require('webpack-merge')
const common = require('./webpack.config.js')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const TerserPlugin = require('terser-webpack-plugin')
module.exports = merge(common, {
mode: 'production',
devtool: 'source-map',
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css'
})
],
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true
}
}
}),
new CssMinimizerPlugin()
],
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
priority: 10
},
common: {
minChunks: 2,
priority: 5,
reuseExistingChunk: true
}
}
},
runtimeChunk: 'single'
}
})
Development configuration:
// webpack.dev.js
const { merge } = require('webpack-merge')
const common = require('./webpack.config.js')
module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
static: './dist',
hot: true,
port: 3000,
open: true,
historyApiFallback: true,
compress: true
}
})
Package.json scripts:
{
"scripts": {
"start": "webpack serve --config webpack.dev.js",
"build": "webpack --config webpack.prod.js",
"analyze": "webpack-bundle-analyzer dist/stats.json"
},
"devDependencies": {
"@babel/core": "^7.23.0",
"@babel/preset-env": "^7.23.0",
"@babel/preset-react": "^7.23.0",
"babel-loader": "^9.1.3",
"css-loader": "^6.8.1",
"css-minimizer-webpack-plugin": "^5.0.1",
"html-webpack-plugin": "^5.5.3",
"mini-css-extract-plugin": "^2.7.6",
"style-loader": "^3.3.3",
"terser-webpack-plugin": "^5.3.9",
"webpack": "^5.89.0",
"webpack-bundle-analyzer": "^4.9.1",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1",
"webpack-merge": "^5.10.0"
}
}
Best Practice Note
Use separate configurations for development and production. Enable source maps in production for debugging. Split chunks to separate vendor code from application code. Use contenthash for long-term caching. Enable hot module replacement in development. Use MiniCssExtractPlugin to extract CSS into separate files. This is how we configure Webpack for CoreUI React applications—optimized production builds with code splitting, asset optimization, and efficient development workflow with hot reloading.



