I had the same question; below are code samples from the solution I developed.
The main thing that helped me was the pug-loader README.md "Embedded resources" section: "Try to use require for all your embedded resources, to process them with webpack."
As long as you require your files properly, Webpack will add them to its dependency graph and process them according to the configuration rules that you define for each file extension type. This processing includes adding the contenthash
to your image filenames in the HTML output in accordance with the method you specify in the file-loader options.name
config object.
Webpack config:
// webpack.common.js
// (edited/trimmed for clarity)
module.exports = {
module: {
rules: [{
test: /\.(jpeg|jpg|png|gif)$/,
use: [
{
loader: "file-loader",
/**
* use `name` to specify how and where images should be outputted
*
* 1. use the image's filepath to set the URL path from which it's served
* 2. use the image's filename and contenthash to set its URL filename
*/
options: {
name: "[path][name].[contenthash].[ext]",
// you may need to set `outputPath` too if you want
// to specify how/where images should be outputted
},
},
{
loader: 'image-webpack-loader'
},
],
}],
},
plugins: [
new HtmlWebpackPlugin({
// set the base path that will be prepended on all relative-path tag attributes
// ex: <img src/>, <link href/>, <script src/>, etc.
publicPath: "/",
}),
],
}
Pug template:
// page.pug
// (edited/trimmed for clarity)
img(
alt="Accessible alternate text"
src=require("./images/image.jpg").default
)
I've also listed my dependency versions below; there may be differences in configuration due to package versioning but the same general principles should apply. Good luck!
// package.json
// (edited/trimmed for clarity)
"devDependencies": {
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.1.0",
"image-webpack-loader": "^7.0.1",
"pug": "^3.0.0",
"pug-loader": "^2.4.0",
"webpack": "^5.22.0",
"webpack-cli": "^4.5.0",
"webpack-dev-server": "^3.11.2",
"webpack-merge": "^5.7.3"
}