When I create an HTML file and I use an image with a relative path, webpack does a good job of saving the file in the dist/images folder as it's instructed to.
However when my JS script adds the same relative image URL then webpack can't seem to find the image and hence I guess is not able to save the image in the dist/images folder
So my question is
Am I doing something wrong in the code below? (I've double checked the paths to the images and even used the original paths in the JS to ensure it's not the path that's wrong)
OR
As the image are loaded by javascript, does this mean that webpack does not save images that are not loaded in the inital HTML file? (I hope this is not true...)
Any advise would be appreciated.
This is my 'template' section in the HTML
<template>
<div >
<div >
<figure >
<picture>
<img
src="./assets/images/product/eyeglass/luxury/chopard/chopard-schf11s.jpg"
alt=""
/>
</picture>
</figure>
</div>
<div >
<h4 >Chopard</h4>
<p >Name of the product</p>
<!-- <p >Description of the product</p> -->
<div data-rating="05">
<span data-rating="05"
>star star star star star</span
>
<span data-votes="100"
>from 100 reviews</span
>
</div>
</div>
<div >
<div >
<span
><span >$120</span></span
>
<span >$120</span>
</div>
<button>Buy Now</button>
</div>
</div>
</template>
and this is my JS
const cardTemplate = document.querySelector("template");
const cards = document.querySelector(".cards");
// deleted the text where the productObject was created to save space
export function displayProductCards() {
console.log(cards);
productObjects.forEach((product) => {
const card = cardTemplate.content.cloneNode(true).children[0];
const productName = card.querySelector(".product__name");
const productBrand = card.querySelector(".product__brand");
const productImage = card.querySelector(".product__image>picture>img");
// const productDescription = card.querySelector(".product__description");
const productPrice = card.querySelector(".product__price");
const productRating = card.querySelector(
".product__rating>span.material-icons"
);
const productVotes = card.querySelector(".product__votes");
// const imgUrl = `./assets/images/product/${product.category.toLowerCase()}/${product.subCategory.toLowerCase()}/${
// product.brandShortname
// }/${product.image}`;
const imgUrl = `./assets/images/product/eyeglass/luxury/chopard/chopard-schf11s.jpg`;
productName.textContent = product.name;
productBrand.textContent = product.brand;
productImage.src = imgUrl;
productPrice.textContent = product.price;
productRating.setAttribute("data-rating", product.rating);
productRating.textContent = setRating(product.rating);
productVotes.textContent = `from ${product.votes} votes`;
cards.appendChild(card);
});
}
function setRating(x) {
let stars = "";
for (let i = 0; i < x; i ) {
stars = "star ";
}
return stars.trim();
}
and this is my webpack config file
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
mode: "development",
entry: "./src/main.js",
output: {
publicPath: "",
filename: "[name].js",
path: path.resolve(__dirname, "dist"),
clean: true,
assetModuleFilename: "./images/[name][ext][query]",
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
}),
new MiniCssExtractPlugin({ filename: "[name].css" }),
],
module: {
rules: [
{
test: /\.s?css$/,
// use: ["style-loader", "css-loader", "sass-loader"],
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
},
{
test: /\.html$/,
use: ["html-loader"],
},
{
test: /\.(svg|png|jpg|jpeg|gif)$/,
type: "asset/resource",
},
],
},
};
CodePudding user response:
This answer is mainly for me in the future if I run into this issue again and for those like me who might be on the same learning path sometime in the future.
So my understanding was that webpack would automatically save all images in the dist/images folder as I had defined in webpack config file
output: {
publicPath: "",
filename: "[name].js",
path: path.resolve(__dirname, "dist"),
clean: true,
assetModuleFilename: "./images/[name][ext][query]",
},
However what I was doing in the JS file was simulating a fetch action where I'd get JSON data and populate the src attribute of all images in the product cards. Expecting these images to be stored in the dist/images folder does not seem logical now in hindsight so basically my expectation was not right. If webpack were to really store all such images in the dist/images folder it would be a huge folder each time I would dynamically fetch a JSON to show all my images on the online store.
So firstly my expectations were not logical and secondly I missed out on this message that was displayed when webpack-dev-server was run ..
<i> [webpack-dev-server] Content not from webpack is served from '/Applications/MAMP/htdocs/sunshyn-optical-store/public' directory
So basically the reason for my images to not show up on the displayed site on localhost was NOT because the images were not being stored in the dist/images folder (which anyways should not be stored there) but because the public path for all relative images was a public folder path that webpack was generating.
So I created a public
folder and added the assets
folder in the public folder and the missing link was fixed. The images showed up fine.
So when expecting to see images that are dynamically updated on the html, ensure that the path exists either by providing absolute paths or ensuring that the relative path is in relation to the public folder.