webpack - scss 无法解析背景图像 url

webpack - scss cannot resolve background-image url

在我的 scss 文件中,我使用 background-image: url("../../../assets/images/home/banner-mobile.png");

应用程序运行成功,但没有显示背景图片:

背景图像 URL 未解析。

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" })],
});

更新 1
当我在 Web Inspector > Sources 中查看 png 时:

当我在浏览器中打开带有 URL 的图像时:

更新二:
当我通过 VSCode 构建和查看图像时,它显示如下:

不确定以下文件是否相关

webpack/Util.js

const path = require('path')

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

我按照这条规则使用文件加载器,它允许我保留文件名和相对路径,所以我的文件夹结构像资产 > 图像,我只需要从路径中删除“资产”:

{
  test: /\.(gif|png|jpg|jpeg)$/,
  loader: 'file-loader',
  options: {
    name: '[path][name].[ext]',
    outputPath: (file) => {
      const p = file.split('assets/')[1];
      return p;
    },
  },
},

这将使您将“assets”文件夹中的所有图像直接放入根包中,并且每个路径都将被复制(例如,assets/images/home/banner.png 将位于您的 images/home/banner.png 上dist 目录),只需确保所有图像都在资产文件夹中,以避免出现名称冲突

由于您使用的是 Webpack 5,我建议您使用 Asset Modules 而不是已弃用的加载器

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

我怀疑您 运行 遇到了文档中提到的资源处理重复问题...

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'.