webpack的file-loader无法加载背景图片。

4
我有这个问题已经一段时间了,看到其他人也遇到了同样的问题,但即使我使用与他们相同的代码,它仍然不能运行,我不知道哪里出错了。 我正在使用react、webpack、babel和scss进行一个项目。起初我创建了一个主要组件,其中包含一个背景图片,加载没有问题,但是当我添加了轮播组件时,我遇到了一个错误,提示我需要一个loader才能显示图像(HTML图像,而不是背景)。我在互联网上搜索了两种loader:url-loader和file-loader,我安装了两者并按照文档中所说,在我的webpack配置文件中添加了一个。图像加载了,但是主要组件的背景图像没有加载,并且所有背景的样式也没有应用。
这是我的webpack配置文件,我尝试放置两个Loader,然后只放置一个,再然后放置另一个,但没有一个可以工作。我尝试了Stackoverflow上的每一个解决方案,但是代码仍然无法工作,并且终端中没有错误。
///////EDIT
我添加了绝对路径,但仍然无法工作。因为如果未获取到图像,我将会收到错误信息,我认为这不是路径问题。我更新了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 文件(其中包含背景图像)

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

我发现如果在url-loader选项中放置 esModule: false,则可以加载图像。


看起来可能是背景图片的相对URL路径出了问题。您能否将图像URL更改为绝对路径并检查背景是否呈现? - dan webb
我在webpack文件中添加了绝对路径,在我的scss文件中以这种方式导入图像,但仍然无法正常工作。我尝试导入一个不存在于我的资产文件夹中的随机图像,结果出现错误,因此路径本身运行良好,并且我正在寻找的图像被调用。我不认为这是路径问题,因为我的理论是加载程序由于某种原因无法获取背景图像。但无论如何,感谢您的建议! - alexgarciaalcuadrado
我有同样的问题。你找到解决方案了吗? - Roberto
不,我尝试了互联网上所有版本的两个加载器的用法,但它们都没有显示背景图像。我知道图片被调用并且路径正确,但由于某种原因样式没有被应用。 - alexgarciaalcuadrado
4个回答

6
这是对我很有效的方法:https://webpack.js.org/guides/asset-management/。你需要已经安装好 css-loader。这个方案不使用 file-loader 或者 url-loader,所以要注意一些影响,但是这是 Webpack 推荐的简单解决方案。我删除了 file-loader 的设置,并更新为:
{
  test: /\.(png|svg|jpg|jpeg|gif)$/i,
  type: 'asset/resource',
},

解释如下:
当使用css-loader时,与上述相似,在您的CSS中使用url('./my-image.png')将发生类似的过程。 加载程序将识别这是一个本地文件,并替换 './my-image.png'。
这对我非常有效,希望它能有所帮助。

5
如果你已经安装了Webpack 5,那么不需要再安装(file-loader, url-loader, raw-loader),因为它们已经包含在Webpack 5中了。只需像没有使用Webpack一样,在CSS文件中引入图片即可使一切正常运作。

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

enter image description here


1

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


0
如果您正在构建一个NextJs应用程序,您可以将所有图像或SVG移动到公共文件夹中,并直接从那里访问它们。
这对我有用。
background-image: url("/pattern.png");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接