webpackwebpack-file-loaderwebpack-5

Webpack 5 How to display images in HTML file


I use webpack for a small little application and so far it works pretty well, except that I have issues in displaying images - I get a 404.

Here i my webpack config:

const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
   entry: {
     index: './src/index.js'
   },
   output: {
     path: path.resolve(__dirname, 'dist'),
     filename: '[name].js'
   },
   module: {
    rules: [
        {
            test: /\.(sa|sc|c)ss$/,
            use: [
            MiniCssExtractPlugin.loader,
              { loader: 'css-loader', options: { importLoaders: 2, sourceMap: true } },
              { loader: 'postcss-loader', options: { sourceMap: true } },
              { loader: 'sass-loader', options: { implementation: require('sass'), sourceMap: true } },
            ]
        },
        {
            test: /\.(png|jpg|gif|svg|eot|ttf|woff)$/,
            use: [
              {
                loader: 'file-loader',
                options: {
                  name: '[name].[ext]',
                  outputPath: 'src/assets/images'
                }
              },
            ],
        },
        {
            test: /\.js$/i,
            use: {
              loader: 'babel-loader',
              options: {
                presets: ['@babel/preset-env'],
              },
            },
        },
        {
            // Extract any CSS content and minimize
            test: /\.css$/,
            use: [
                MiniCssExtractPlugin.loader,
                { loader: 'css-loader', options: { importLoaders: 1 } },
                { loader: 'postcss-loader' }
            ]
        }  
      ]
   },
   plugins: [
      new HtmlWebpackPlugin({
        template: './dist/index.html',
        inject: 'body',
        chunks: ['index'],
        filename: 'index.html'
      }),
      new MiniCssExtractPlugin({
        filename: 'src/css/[name].min.css'
     }),
  ],
  devServer: {
    watchContentBase: true,
    contentBase: path.resolve(__dirname, 'dist'),
    open: true
  }
};

then in my index.html, I try to do this:

<img class="object-cover z-0 w-full h-full" src='/src/assets/images/top_image.png'>

but like I mentioned before, I get 404...

Can someone help me out?


Solution

  • You need to change your legacy assets loaders... For images, it's recommended to use asset/resource.

    Use asset/resource instead file-loader. something like:

    edit your rule:

    {
       test: /\.(png|jpg|gif|svg|eot|ttf|woff)$/,
       type: 'asset/resource'
    }
    

    and add in your webpack.output this:

    output: {
     path: path.resolve(__dirname, 'dist'),
     filename: '[name].js',
     assetModuleFilename: 'src/assets/images/[name][ext]'
    }
    

    You can see more details on Webpack assets loader guide