I am using webpack 5 and I currently have the following setup:
- webpack.prod.js - where I have some specific configs for production (e.g. image compression, devtool, CSS minification, specific meta tags values)
- webpack.dev.js - where I have some specific configs for development (e.g. no image compression, no CSS minification, specific meta tags values)
The issue I am currently facing is that I am unable to get webpack dev server live reloading to work (this apply to all file types). I've been through the docs but no luck so far.
As far as I understand, when in development mode, webpack runs stuff in memory rather than in disk (which is supposed to be faster and that is great!). For some reason it appears that the watcher is not reacting to changes in the files specified in the devServer.watchFiles
config. I was expecting webpack to detect changes on a typescript file, compile it and reload, but that's not happening.
You can find the contents of both files below.
webpack.prod.js:
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require('terser-webpack-plugin');
const ImageMinimizerPlugin = require('image-minimizer-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const buildPath = path.resolve(__dirname, 'dist');
module.exports = {
//devtool: 'source-map',
entry: {
index: "./src/index/index.ts",
error: "./src/error/error.ts",
},
output: {
filename: "js/[name].[contenthash].js",
path: buildPath,
clean: true,
},
module: {
rules: [{
test: /\.ts$/i,
exclude: /node_modules/,
use: "ts-loader",
},
{
test: /\.html$/i,
exclude: /node_modules/,
use: "html-loader",
},
{
test: /\.css$/i,
exclude: /node_modules/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
]
},
{
test: /\.png$/i,
exclude: /node_modules/,
type: "asset/resource",
generator: {
filename: "img/[name].[contenthash][ext]",
},
},
{
test: /\.(woff|woff2|ttf)$/i,
exclude: /node_modules/,
type: "asset/resource",
generator: {
filename: "fonts/[name].[contenthash][ext]",
},
},
{
test: /\.mp3$/i,
exclude: /node_modules/,
type: "asset/resource",
generator: {
filename: "[name].[contenthash][ext]",
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index/index.ejs",
inject: "body",
chunks: ["index"],
filename: "index.html",
meta: {
"robots": {
name: "robots",
content: "index,follow"
},
},
}),
new HtmlWebpackPlugin({
template: "./src/error/error.html",
inject: "body",
chunks: ["error"],
filename: "error.html",
}),
new MiniCssExtractPlugin({
filename: "css/[name].[contenthash].css",
chunkFilename: "css/[id].[contenthash].css",
}),
new CopyPlugin({
patterns: [{
from: "src/robots.txt",
to: "robots.txt",
}, ],
}),
],
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
parallel: true,
}),
new CssMinimizerPlugin(),
new ImageMinimizerPlugin({
minimizer: {
implementation: ImageMinimizerPlugin.imageminMinify,
options: {
plugins: [
["imagemin-pngquant", {
quality: [0.5, 0.9]
}],
],
},
},
}),
],
},
};
webpack.dev.js:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
devtool: "eval-cheap-module-source-map",
entry: {
index: "./src/index/index.ts",
error: "./src/error/error.ts",
},
devServer: {
watchFiles: [path.resolve(__dirname, "src/**/*")],
open: true,
},
module: {
rules: [
{
test: /\.ts$/i,
exclude: /node_modules/,
use: "ts-loader",
},
{
test: /\.html$/i,
exclude: /node_modules/,
use: "html-loader",
},
{
test: /\.css$/i,
exclude: /node_modules/,
use: ["style-loader", "css-loader"]
},
{
test: /\.png$/i,
exclude: /node_modules/,
type: "asset/resource",
generator: {
filename: "img/[name].[contenthash][ext]",
},
},
{
test: /\.(woff|woff2|ttf)$/i,
exclude: /node_modules/,
type: "asset/resource",
generator: {
filename: "fonts/[name].[contenthash][ext]",
},
},
{
test: /\.mp3$/i,
exclude: /node_modules/,
type: "asset/resource",
generator: {
filename: "[name].[contenthash][ext]",
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index/index.ejs",
inject: "body",
chunks: ["index"],
filename: "index.html",
meta: {
"robots": { name: "robots", content: "noindex, nofollow" },
},
}),
new HtmlWebpackPlugin({
template: "./src/error/error.html",
inject: "body",
chunks: ["error"],
filename: "error.html"
}),
],
optimization: {
runtimeChunk: "single",
},
};