6

My webpack.config.js file

const path = require('path');

const HtmlWebPackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
  entry: {
    index: './src/js/index.js',
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: ['babel-loader'],
      },
      {
        test: /\.html$/,
        use: [
          {
            loader: 'html-loader',
            options: { minimize: true },
          },
        ],
      },
      {
        test: /\.(jpg|png)$/,
        use: {
          loader: 'url-loader',
        },
      },
      {
        test: /\.(css|scss)$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'postcss-loader',
          'sass-loader',
        ],
      },
    ],
  },

  output: {
    path: path.resolve(__dirname, './dist'),
    filename: './js/[name].bundle.js',
  },

  plugins: [
    new HtmlWebPackPlugin({
      template: path.resolve(__dirname, './src/index.html'),
      filename: 'index.html',
      chunks: ['index'],
    }),

    new CleanWebpackPlugin(),

    new MiniCssExtractPlugin({
      filename: './css/[name].css',
    }),

    new CopyWebpackPlugin({
      patterns: [{ from: './src/assets', to: './assets' }],
    }),
  ],

  devtool: 'source-map',
  mode: 'development',
};

my files structure where the problem occurs:

enter image description here

what is strange, when I run npm run build in the terminal, all directories are loaded correctly I mean: background-image works, and slider directory with images is loaded, but there is also loaded some additional files with random numerical names

enter image description here

and those three additional .png files are loaded to my index.html as img1.png img2.png and img3.png files which not work on my website, they just do not want to load

3 Answers3

2

This is caused by Webpack 5's new Asset Modules. You can either remove url-loader and specify the asset type like so:

{
    test: /\.(jpg|png)$/,
    type: 'asset/inline',
},

Or you can disable asset modules by adding type: 'javascript/auto' to your rule:

{
  test: /\.(jpg|png)$/,
  use: {
    loader: 'url-loader',
  },
  type: 'javascript/auto'
}

See the documentation to learn more, and to see how to do this for file-loader and raw-loader as well.

Mitch Talmadge
  • 4,638
  • 3
  • 26
  • 44
0

I think your image files are probably double-processed, because you once just copy your assets folder to your dist output folder, and then you somewhere probably use the images with url("./someImage") or similar in your css files, which get processed by your css loader or css Mini Exctract plugin, which creates that cryptic image asset output, that then gets used in your html files, look at here: webpack.js.org/guides/asset-management/#loading-images.. I dont know why you need to copy your assets folder but that looks redundant to me...

EDIT: I'm not an expert at this, but after investigating some hours into this weird error, I realized that the paths were set correctly to the image files, but the image output that file-loader or other loaders generate with the image (like 0f9b8be78d378ad2ef78.jpg) seems to be something different, if I open them in vscode editor in standard text/binary editor, I get this line: export default __webpack_public_path__ + "someimage.jpg";, with url-loader its the binary64 converted string with data-url(..).. so it seems its not for the purpose to use it in static html files..

I then used the recommended way to do it like this in webpack.config.js:

        {   test: /\.(jpg|png)$/, 
            type: 'asset/resource', }

after that my image was shown correctly, I have no idea what file-loader etc. is doing..

here is my final webpack.config.js:

const path = require('path')

const HtmlWebPackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
    entry: {
        index: './src/js/index.js',
    },
    devServer: {
        port: 5757,
        contentBase: path.resolve(__dirname, 'src'),
        publicPath: '/src',
    },

    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: ['babel-loader'],
            },
            {
                test: /\.html$/,
                use: [
                    {
                        loader: 'html-loader',
                        options: { minimize: true },
                    },
                ],
            },
            {
                test: /\.(jpg|png)$/,
                type: 'asset/resource',

            },
            {
                test: /\.(css|scss)$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader',
                    'sass-loader',
                ],
            },
        ],
    },

    output: {
        path: path.resolve(__dirname, './build'),
        //publicPath: './assets/images',
    },

    plugins: [
        new HtmlWebPackPlugin({
            template: path.resolve(__dirname, './src/index.html'),
            filename: 'index.html',
            inject: 'body',
        }),

        new MiniCssExtractPlugin({
            filename: './css/[name].css',
        }),
    ],

    devtool: 'source-map',
    mode: 'development',
}
MMMM
  • 3,320
  • 8
  • 43
  • 80
  • I tried to delete CopyWebpackPlugin role, then used this { test: /\.(png|svg|jpg|jpeg|gif)$/i, type: 'asset/resource', }, imported files in index.js and it still does not work –  Apr 20 '21 at 22:53
  • 1
    hmmm can you try for "output" config to add the `publicPath: '/'` option, and otherwise, maybe try file-loader: `npm i file-loader` and in config: `{ test: /\.(jpe?g|png|gif|svg)$/i, use: 'file-loader' }` – MMMM Apr 20 '21 at 23:03
  • then i got all photos correctly loaded with random numerical name and additional i got 3 other .png files with random numerical values but with error 'Image not loaded' like before i also do not get my assets folder, all png files are loaded into main ./dist directory –  Apr 20 '21 at 23:10
  • hmmm weird, I found another thread about it here: https://stackoverflow.com/questions/35369419/how-to-use-images-in-css-with-webpack.. but you tried publicPath already? could you just add the code where you import your images in your original thread? – MMMM Apr 20 '21 at 23:13
  • you mean the html where the images are imported? –  Apr 20 '21 at 23:16
  • yeah and the css where you use or import the images.. I assume you import your css in your html? – MMMM Apr 20 '21 at 23:31
  • I import css in index.js, because its automatically imported into html by webpack –  Apr 21 '21 at 06:26
  • images are improted into html like that - `
    img
    `
    –  Apr 21 '21 at 06:29
  • hmm it works for me, I used your webpack config file, and in my dist folder, the image src in the html file is replaced like this: ``, but I had to import the image in the .js file entry point like that: `let image = import('../assets/images/someimage.jpg')` maybe you forgot that? – MMMM Apr 21 '21 at 09:10
  • EDIT: My above comment is true for webpack build, but if you use .eg webpack serve with `webpack-dev-server`, the output is different, in my webpack config, I added following options: `devServer: { port: 5757, contentBase: path.resolve(__dirname, 'src'), publicPath: '/src', },` now, the image path is the original image source from my html code, I am not sure what u was using, build or dev-server.... – MMMM Apr 21 '21 at 09:36
  • could u show me ur config with all changes u did? –  Apr 21 '21 at 12:15
0

I have just solved my every problem because after using the answer from @ChillaBee, images were working correctly expect my background photo which I used in css file as url. Use the answer above but change

{
    test: /\.(jpg|png)$/,
    type: 'asset/resource',
},

to

{
    test: /\.(jpg|png)$/,
    type: 'asset/inline',
},

now images from html and css are loaded correctly