React从public文件夹导入图片

4

我尝试从公共目录获取静态图片,但未找到。我没有使用CRA,因此可能是我缺少Webpack的某些配置。在开发模式下使用file-loader模块并导入图像有效,但在我的生产服务器规格中无法正常工作。

我的项目结构:

\public
   \static
      \images
         image.png
\src
   \component
      component.js
...
package.json
webpack.common.js
webpack.dev.js
webpack.prod.js

在component.js中,我想要像这样获取静态文件夹static/images中的image.jpg:
  <img src='/static/images/image.png'></img>

但是我得到了404未找到的错误。

我的webpack.commom.js文件:

const CleanWebPackPlugin = require('clean-webpack-plugin')
const HtmlWebPackPlugin = require('html-webpack-plugin')
const path = require('path')

module.exports = {
    entry: {
        main: './src/index.js'
    },
    output: {
        filename: '[name].[hash].js',
        path: path.resolve('./dist'),
        publicPath: "/"
    },
    module:{
        rules:[
            {
                test: /\.js$/,
                exclude: ['/node_modules'],
                use: [{ loader: 'babel-loader'}],
            },
            {
                test: /\.s?(a|c)ss$/,
                use: [{
                    loader: 'style-loader'
                }, {
                    loader: 'css-loader'
                },{
                    loader: 'sass-loader'
                }]
            },
            {
                test: /\.(png|jpe?g|gif)$/,
                use: [
                  {
                    loader: 'file-loader',
                    options: {},
                  },
                ],
              },

        ]
    },
    plugins: [
        new HtmlWebPackPlugin({
            template: 'index.html'
        }),
        new CleanWebPackPlugin(),
    ],
}

同时还有开发版本:

module.exports = merge(common, {
    mode: 'development',
    devServer: {
        host: 'localhost',
        port: 3000,
        open: true,
        historyApiFallback: true,
        publicPath: "/",
    }
})

谢谢您的提前帮助。


几件事情:您将'src'设置为'/static/image.png',但根据您的项目结构,它应该是'/static/images/image.png'。那是打错字了吗?生产构建运行后,您的'dist/'文件夹是什么样子?它包括那个图像文件吗? - callmeroot
这确实是一个打字错误。在生产的dist/文件夹中,只有当我通过loader webpack插件导入时才会出现图像,这对我来说不是一个好选择。 - 7xRobin
3个回答

3

我想你希望能够多次展示这种图片。在这种情况下,在jsx代码中写两三次'%PUBLIC_URL%/img/static/images/image.png'或{process.env.PUBLIC_URL + '/img/static/images/image.png'}是很烦人的。基本上,如果您的应用程序以src文件夹为根目录,则无法从公共文件夹导入图像(除非使用插件)。但是,对于我来说,我找到了一个相当简单的解决方案。类似于这样:

import React from 'react'

var path = process.env.PUBLIC_URL;
var image = "/img/static/images/image.png";

然后,在JSX代码中:

<img src={path + image}/>

对我有用,希望对任何人都有帮助!:D


1
您正在使用 file-loader 作为 webpack 插件,它不能以“只是将 public 目录的目录结构镜像到 dist”方式工作。您可以在此处找到该插件的文档:https://webpack.js.org/loaders/file-loader/ 基本上,该插件的作用是,如果您导入一个图像文件(实际上是通过编程方式导入,而不仅仅是使用其路径的字符串引用),则该文件会被复制到您的 dist 目录中,可能会重命名,然后在编译后的源代码中插入正确的文件名。
因此,在您的情况下,如果您想使用 file-loader 解决问题,您应该像这样引用图像文件:
// Relative path to image file from js file
import imageFile from './assets/image.png';

// ...
const component = props => <img src={imageFile}></img>;

如果您想使用实际上只是将public目录镜像到dist目录的方法,您需要使用一个额外的webpack插件来实现(例如https://dev59.com/wF4c5IYBdhLWcg3wssBs#33374807)。
顺便说一下,我假设它在开发模式下工作,因为您将'/'设置为公共路径,所以开发服务器也会将根目录中的所有内容提供服务。然而,这与您试图实现的将文件复制到dist是不同的。

使用file-loader导入可以工作,但我需要直接从公共路径访问源文件,例如<img src='/static/images/image.png'></img>。但是开发服务器找不到源文件,这是一个大问题。copy-webpack-plugin解决了我的问题,但我不确定为什么。无论如何,谢谢。 - 7xRobin

0

不确定这是否有帮助,但我会尝试一下

尝试将公共路径添加到您的dist文件夹中,类似于以下内容

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

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