Search code examples
javascriptreactjssasswebpack-5urlloader

webpack - scss cannot resolve background-image url


In my scss file, I use background-image: url("../../../assets/images/home/banner-mobile.png");

The application runs successfully, but no background image is shown:

The background image URL is not resolved. enter image description here

webpack/webpack.base.js

const webpack = require("webpack");
const path = require("path");

const utils = require("./utils");

const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: "./src/index.jsx",
  resolve: {
    alias: {
      "@": utils.resolve("src")
    },
    extensions: ["*", ".js", ".jsx"],
    fallback: {...},
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          {
            loader: "style-loader",
          },
          {
            loader: "css-loader",
          },
          {
            loader: "sass-loader"
          },
          {
            loader: "sass-resources-loader",
            options: {
              resources: ["./src/assets/scss/main.scss"],
            },
          },
        ],
      },
      {
        test: /\.(png|jpg|gif)$/i,
        use: [
          {
            loader: "url-loader",
            options: {
              limit: 8192
            },
          },
        ],
      }
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "public/index.html",
      filename: "index.html",
      inject: true,
    })
  ],
};

webpack/webpack.dev.js

const { merge } = require("webpack-merge");
const base = require("./webpack.base");

const Dotenv = require("dotenv-webpack");

module.exports = merge(base, {
  mode: "development",
  devtool: "inline-source-map",
  output: {
    publicPath: '/',
  },
  devServer: {
    port: 3000,
    static: true,
    static: 'dist'
  },
  plugins: [new Dotenv({ path: "./.env.development" })],
});

Update 1
When I view the png in Web Inspector > Sources: enter image description here

When I open the image with its URL in the browser: enter image description here

Update 2:
When I build and view the image via VSCode, it shows below: enter image description here

Not sure if the below file-is related

webpack/Util.js

const path = require('path')

module.exports = {
  resolve: function(dir) {
    return path.join(__dirname, '..', dir)
  }
}

Solution

  • Since you're using Webpack 5, I'd recommend using Asset Modules instead of the deprecated loaders

    module: {
      rules: [
        // ...
        {
          test: /\.(png|jpg|gif)$/i,
          type: "asset",
          parser: {
            dataUrlCondition: {
              maxSize: 8192
            }
          }
        }
      ]
    }
    

    I suspect you were running into a resource handling duplication issue as noted in the documentation...

    When using the old assets loaders (i.e. file-loader / url-loader / raw-loader) along with Asset Module in webpack 5, you might want to stop Asset Module from processing your assets again as that would result in asset duplication. This can be done by setting asset's module type to 'javascript/auto'.