const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const isProduction = process.env.NODE_ENV === 'production';
const isDevelopment = !isProduction;
module.exports = {
mode: isProduction ? 'production' : 'development',
bail: isProduction,
context: path.join(__dirname),
entry: {
src: './index.jsx',
},
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
filename: '[name].[chunkhash:8].js',
},
resolve: {
alias: {
react: require.resolve('react'),
'react-dom/client': require.resolve('react-dom/client'),
'react-dom': require.resolve('react-dom'),
},
extensions: ['.js', '.jsx'],
symlinks: false,
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules(?!\/@wojtekmaj\/react-async-button)/,
use: [
{
loader: 'babel-loader',
options: {
babelrcRoots: ['.', '../'],
plugins: [isDevelopment && 'react-refresh/babel'].filter(Boolean),
},
},
],
},
{
test: /\.css$/,
use: [isProduction ? MiniCssExtractPlugin.loader : 'style-loader', 'css-loader'],
},
].filter(Boolean),
},
plugins: [
new HtmlWebpackPlugin({
template: 'index.html',
}),
isProduction &&
new MiniCssExtractPlugin({
filename: '[name].[chunkhash:8].css',
chunkFilename: '[name].[chunkhash:8].css',
}),
isDevelopment && new ReactRefreshWebpackPlugin(),
].filter(Boolean),
optimization: {
moduleIds: 'named',
},
stats: {
assetsSort: '!size',
entrypoints: false,
},
devServer: {
compress: true,
historyApiFallback: true, // respond to 404s with index.html
hot: true, // enable HMR on the server
port: 3000,
},
};