webpack file-loader 不加载背景图片

webpack file-loader does not load background image

我遇到这个问题已经有一段时间了,我看到其他人也有这个问题,但即使我和他们有相同的代码,它仍然无法正常工作,我不知道我在做什么做错了。 我正在为一个项目使用 react、webpack、babel 和 scss。起初我创建了一个主要组件,它有一个背景图像,没有问题,但是当我添加一个旋转木马组件时,我有一个错误,说我需要一个加载器来显示图像(html 图像,而不是 bakground ).所以我在网上查了一下,出现了两个加载器:url-loader 和 file-loader,我安装了两个加载器,并按照文档中的说明在我的 webpack 配置文件中添加了一个。图片加载了,但是主组件的背景图没有加载,不仅如此,背景的所有样式也没有应用。

这是我的 webpack 配置文件,我尝试放置两个加载器,然后只放置一个,然后是另一个,但其中 none 有效。我尝试了遇到 Whosebug 的所有解决方案,但代码无法正常工作,而且我的终端中没有错误。

///////编辑

我添加了 absolute paht,但它仍然无法正常工作。获取图像是因为如果不是这样我会收到错误所以我认为这不是路径问题。 我更新了 webpack 配置文件

const HtmlWebPackPlugin = require("html-webpack-plugin");
const path = require("path");
const htmlPlugin = new HtmlWebPackPlugin({
 template: "./src/index.html",
 filename: "./index.html"
});




module.exports = {
mode: "development",
resolve: {
  alias: {
    Assets: path.resolve(__dirname, 'src/assets/')
  }
},
  module: {
    rules: [{
   test: /\.js$/,
   exclude: /node_modules/,
   use: {
     loader: "babel-loader"
   }
 },
  {
   test: /\.s?css$/,
   use: ["style-loader", "css-loader", "sass-loader"]
  },
  {
    test: /\.(png|jpg|gif)$/i,
    use: [
      {
        loader: 'url-loader',
        options: {
          limit: 10000,
          esModule: false
        },
      },
    ]
  }
]},
 plugins: [htmlPlugin],
 devServer:{
   historyApiFallback : true
 }
}

这是我的主要组件及其 scss 文件(bakground 图像所在的位置)

React 组件

import React from "react";
import { NavBar } from "../components/NavBar";
import CarouselComponent from "../components/Carousel";

export const MainPage = () => {
    return (
        <div>
        <NavBar />
        <div>
            <div className="main">
                <h1>Find a new musical to watch!</h1>
                <a className="main__btn" href="/musicals">See categories</a>
            </div>
            <div className="login-info">
                <h2 className= "login-info__login">See our forum for reacomendations and post your own!</h2>
                <div className="login-info__btn-login-position">
                    <a className="btn login-btn-position-config" href="#"><strong>Loging</strong></a>   
                </div>
                <span></span>
                <h2 className= "login-info__create-account">Don't have an account? Create one!</h2>
                <div className="login-info__btn-create-position">
                <   a className="btn login-btn-position-config" href="#"><strong>Create account</strong></a> 
                </div>
           </div>
            <CarouselComponent />
        </div>
        </div>
    )
}

Scss 组件

body{ 
    padding: 56px 50px 0 50px;
    background-color: $color-background;
}


.main{
    font-family: $primary-title-font;
    height: 90%;
    background: url(Assets/main_background.jpg) no-repeat center center; 
    -webkit-background-size: cover; 
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
    
    h1{
        background-image: linear-gradient(90deg, rgba(1,50,1,1) 5%, rgba(70,82,25,1) 51%, rgba(78,82,29,1) 87%);
        background-size: 100%; 
        background-clip: text;
        -webkit-background-clip: text;
        -moz-background-clip: text;
        -webkit-text-fill-color: transparent; 
        -moz-text-fill-color: transparent;
        position: absolute;
        top: 15rem;
        left: 5rem;
        font-size: 5rem;
        
    }

    &__btn{ 
        position: absolute; 
        top: 350px;
        left: 459px;
        border-radius: 10% / 20%;
        padding: 1rem;
        text-decoration: none;
        color: $primary-black-color;
        background: $golden-button;
        font-size: 1.5rem;

        &:hover{
            color: $primary-black-color;
        }

        &:active{
            transform: translateY(2px);
        }
    }
}


这是带有 scss 的轮播组件

React 组件

import React, { Component } from "react";
import "react-responsive-carousel/lib/styles/carousel.min.css"; 
import { Carousel } from 'react-responsive-carousel';
import hamilton from "../assets/hamilton.jpg";
import six from "../assets/six_the_musical.jpg";
import hadestown from "../assets/hadestown.jpg";
import theGuy from "../assets/the_guy_who_didnt_like_musicals.png";

class CarouselComponent extends Component {
    render (){
        return (
            <Carousel autoPlay = {true} infiniteLoop={true} interval={4000} showStatus={false} useKeyboardArrows={true} showThumbs={false}>
                <div className="carousel__box-1">
                    <img src={hamilton} alt="Hamilton wallpaper"/>
                </div>
                <div className="carousel__box-2">
                    <img src={six} alt="Six wallpaper"/>
                </div>
                <div className="carousel__box-3">
                    <img src={hadestown} alt="Hadestown wallpaper"/>
                </div>
                <div className="carousel__box-4">
                    <img src={theGuy} alt="The guy who didnt like musicals wallpaper"/>
                </div>
            </Carousel>
        )
    }
}

export default CarouselComponent;

Scss 组件

.carousel__box{
    height: 9rem;

    img{
        min-width: 100%;
        min-height: 100%;
    }
}

我还会添加我的文件夹结构以备不时之需

/project
  /dist
  /node_modules
  /src
    /assets
       (all the images are stored here)
    /components
       card.js
       cardBlock.js
       carousel.js
       navbar.js
    /pages
       main.js
       musicals.js
       notFound.js
    /sass
       (all scss are stored here, there is a styles.scss that imports the rest of files and it's 
       called in index.js)
    index.html
    index.js (imports all react component an renders them in index.html)
    .babelrc
    packaje.json
    packaje-lock.json
    webpack.config.js

////// 新编辑

我发现如果将 esModule: false 放入 url-loader 选项中,图像就会被加载。

在 url-loader 选项中添加 esModule: false 图像帮助了我,虽然我不确定为什么,如果有人遇到同样的问题,你应该尝试这个技巧。

这对我有用https://webpack.js.org/guides/asset-management/。您需要已经设置 css-loader。这不是使用 file-loaderurl-loader,因此请注意其含义,但它是 Webpack 推荐的简单解决方案。我删除了 file-loader 的设置并更新为:

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

解释是这样的:

When using the css-loader, as shown above, a similar process will occur for url('./my-image.png') within your CSS. The loader will recognize this is a local file, and replace the './my-image.png'

这对我来说非常有效,希望对您有所帮助。

如果你有 webpack 5 那么就不要安装 (file-loader, url-loader, raw-loader) 它们是 5 自带的。一切都可以,只需将图像包含在 css 文件就像没有 webpack 一样。

https://webpack.js.org/guides/asset-modules/