React не загружает локальные изображения


123

Я создаю небольшое приложение для реагирования, и мои локальные изображения не загружаются. Изображения вроде placehold.it/200x200загружаются. Подумал может может быть что то с сервером?

Вот мой App.js

import React, { Component } from 'react';

class App extends Component {
    render() {
        return (
            <div className="home-container">
                <div className="home-content">
                    <div className="home-text">
                        <h1>foo</h1>
                    </div>
                    <div className="home-arrow">
                        <p className="arrow-text">
                            Vzdělání
                        </p>
                        <img src={"/images/resto.png"} />
                    </div>
                </div>
            </div>
        );
    }
}

export default App;

index.js:

import React, { Component } from 'react';
import { render } from 'react-dom';
import { Router, Route, Link } from 'react-router';
import { createHistory } from 'history';
import App from './components/app';

let history = createHistory();

render(
    <Router history={history} >
        <Route path="/" component={App} >
            <Route path="vzdelani" component="" />
            <Route path="znalosti" component="" />
            <Route path="prace" component="" />
            <Route path="kontakt" component="" />
        </Route>
        <Route path="*" component="" />
    </Router>,
    document.getElementById('app')
);

и server.js:

var path = require('path');
var express = require('express');
var webpack = require('webpack');
var config = require('./webpack.config.dev');

var app = express();
var compiler = webpack(config);

app.use(require('webpack-dev-middleware')(compiler, {
  noInfo: true,
  publicPath: config.output.publicPath
}));

app.use(require('webpack-hot-middleware')(compiler));

app.get('*', function(req, res) {
  res.sendFile(path.join(__dirname, 'index.html'));
});

app.listen(3000, 'localhost', function(err) {
  if (err) {
    console.log(err);
    return;
  }

  console.log('Listening at http://localhost:3000');
});

4
Обычно это означает, что ваш локальный веб-сервер не обслуживает изображения или указанный вами URL-адрес неверен. Откройте консоль браузера и проверьте, нет ли у вас ошибок, например 404 not found.
Марио Таке

5
Folks! просто используйте require(). например src = {require ("image path")}
Нирадж Севани,

просто используйте require () = src = {require ("image path")}
xAtifx

Ответы:


271

При использовании Webpack вам нужны requireизображения, чтобы Webpack мог их обрабатывать, что объясняет, почему внешние изображения загружаются, а внутренние - нет, поэтому вместо <img src={"/images/resto.png"} />вам нужно использовать <img src={require('/images/image-name.png')} />замену image-name.png на правильное имя изображения для каждого из них. Таким образом, Webpack сможет обрабатывать и заменять исходный img.


1
Но как импортировать требовать? Browserify? Если да, то как? Я пробовал import {require} from 'browserify'. Но это не работает.
Shubham Kushwah

1
@ShubhamKushwah Вам не нужно импортировать require. Он предоставляется как часть commonjs. См stackoverflow.com/a/33251937/4103908 и viget.com/articles/gulp-browserify-starter-faq для получения дополнительной информации , которая может помочь вам с помощью требуют и browserify с помощью Глоток.
Thomas

@Thomas Проблема с внутренними и внешними изображениями, они не загружаются при первой загрузке страницы, но если я обновлю их, они загрузятся. Итак, как мне решить эту проблему - пожалуйста, помогите!
Shubham Kushwah

6
Получение ошибки: Module not found: Error: Can't resolve 'MyPNG.png' in 'C:...\app\components\images'. Путь к файлу выглядит хорошо !.
reubenjohn 06

2
src = {require ('./ responseLogo.svg')} начните свой путь с "./" для текущего каталога, чтобы избежать ошибок.
cheesey

53

Я начал создавать свое приложение с помощью create-react-app (см. Вкладку «Создание нового приложения»). README.md, поставляемый с ним, дает следующий пример:

import React from 'react';
import logo from './logo.png'; // Tell Webpack this JS file uses this image

console.log(logo); // /logo.84287d09.png

function Header() {
  // Import result is the URL of your image
  return <img src={logo} alt="Logo" />;
}

export default Header;

Это отлично сработало для меня. Вот ссылка на главный документ для этого README , в котором объясняется (отрывок):

... Вы можете импортировать файл прямо в модуль JavaScript. Это указывает Webpack включить этот файл в пакет. В отличие от импорта CSS, импорт файла дает вам строковое значение. Это значение - последний путь, на который вы можете ссылаться в своем коде, например, как атрибут src изображения или href ссылки на PDF.

Чтобы уменьшить количество запросов к серверу, при импорте изображений размером менее 10 000 байт вместо пути возвращается URI данных. Это относится к файлам следующих расширений: bmp, gif, jpg, jpeg и png ...


Кроме того, вы также должны экспортировать изображения откуда-то, чтобы иметь возможность импортировать их куда угодно, а не только из одного и того же каталога, что было бы в случае, если бы они не экспортировались. Они должны будут находиться в том же каталоге, что и компонент, в который они были импортированы. Вы заметите, что в любом новом приложении React, созданном, например, с помощью CRA, файл logo.svg находится в том же каталоге, что и App.js, куда он импортируется. Я написала статью об импорте изображений в React здесь: blog.hellojs.org/importing-images-in-react-c76f0dfcb552
Мария Кэмпбелл,

В продолжение комментария выше, если вы используете url-loader веб-пакета, как показывает фандро выше, ваши файлы, соответствующие тестовым расширениям в веб-пакете, автоматически экспортируются и делают их доступными для импорта сохранения, которое Хоукай Паркер показал выше.
dave4jr

Я знаю, что это действительно старая тема, но все же; как ты заставил это работать? В моем случае программа пытается «прочитать изображение» ... что приводит к ужасной ошибке: Unexpected character '�' (1:0) > 1 | �PNG | ^ 2 | 3 | 4 | IHDR��r~ipHYs���o�d��IDATx^�}���Ü�d7�w¿½ï¿½ ��JzH!�K�ï...
В. Куртуа

@ V.Courtois извините - я не работал с этим с тех пор, и я не помню больше подробностей прямо сейчас :(
Hawkeye Parker

Мне пришлось добавить свои изображения в общую папку в проекте Create-React-App.
pixel 67

29

Другой способ сделать:

Во- первых, установить эти модули: url-loader,file-loader

Используя npm: npm install --save-dev url-loader file-loader

Затем добавьте это в свою конфигурацию Webpack:

module: {
    loaders: [
      { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
    ]
  }

limit: Ограничение байтов для встроенных файлов в качестве URL-адреса данных

Вам необходимо установить оба модуля: url-loaderиfile-loader

Наконец, вы можете:

<img src={require('./my-path/images/my-image.png')}/>

Вы можете подробнее изучить эти загрузчики здесь:

url-загрузчик: https://www.npmjs.com/package/url-loader

файл-загрузчик: https://www.npmjs.com/package/file-loader


1
Надеюсь, это поможет другим. Мне тоже пришлось это сделать; Установите url-загрузчик. npm install --save-dev url-loader
LUser

1
Я боролся с этим вчера вечером, и этот пост был на моем экране этим утром :) Если вы видите что-то вроде Module build failed: SyntaxError: c:/contrivedpath/images/profile.jpg: Unexpected character '�' (1:0), все, что вам нужно сделать, это добавить эту конфигурацию url-loader выше в конфигурацию вашего webpack, установить npm url-loaderИ file-loaderи вы быть функциональным. Я протестировал, чтобы убедиться, нужен загрузчик файлов.
agm1984

1
@ agm1984 Я выполнил описанные выше действия и все еще получаю ERROR in ./src/images/imagename.png Module parse failed: Unexpected character '�' (1:0)сообщение. Любые идеи?
Дэвид

это было действительно полезно, но я не могу понять, почему <img src = "images / myimage.png" /> не работает !! Не могли бы вы объяснить?
Марк

Сделал все, что ты сказал, но без кубиков. Webpack строит без жалоб, я вижу, что мое изображение PNG было перемещено в выходной каталог, но оно не загружается на страницу. Когда я проверяю код, он просто говорит, src=[Object module]а когда я наводю указатель мыши, он говорит: «Не удалось загрузить изображение»
JSStuball

4

На самом деле я хотел бы прокомментировать, но я еще не авторизован. Вот почему это делает вид, что это следующий ответ, а это не так.

import React from 'react';
import logo from './logo.png'; // Tell Webpack this JS file uses this image
console.log(logo); // /logo.84287d09.png

function Header() {
// Import result is the URL of your image
  return <img src={logo} alt="Logo" />;

Я хотел бы продолжить этот путь. Это работает плавно, когда есть изображение, которое можно просто вставить. В моем случае это немного сложнее: мне нужно сопоставить несколько изображений. Пока что единственный работоспособный способ сделать это, который я нашел, заключается в следующем

import upperBody from './upperBody.png';
import lowerBody from './lowerBody.png';
import aesthetics from './aesthetics.png';

let obj={upperBody:upperBody, lowerBody:lowerBody, aesthetics:aesthetics, agility:agility, endurance:endurance}

{Object.keys(skills).map((skill) => {
 return ( <img className = 'icon-size' src={obj[skill]}/> 

Итак, мой вопрос: есть ли более простые способы обработки этих изображений? Излишне говорить, что в более общем случае количество файлов, которые необходимо буквально импортировать, может быть огромным, как и количество ключей в объекте. (Объект в этом коде явно задействован для ссылки по именам - его ключам) В моем случае процедуры, связанные с требованиями, не работали - загрузчики генерировали ошибки странного типа во время установки и не показывали никаких признаков работы; и требование само по себе тоже не сработало.


2

Я просто хотел оставить следующее, что усиливает принятый выше ответ.

В дополнение к принятому ответу вы можете немного облегчить себе жизнь, указав aliasпуть в Webpack, поэтому вам не нужно беспокоиться о том, где находится изображение относительно файла, в котором вы сейчас находитесь. См. Пример ниже :

Файл Webpack:

module.exports = {
  resolve: {
    modules: ['node_modules'],
    alias: {
      public: path.join(__dirname, './public')
    }
  },
}

Использование:

<img src={require("public/img/resto.ong")} />

2

Я тоже хотел бы добавить к ответам @Hawkeye Parker и @Kiszuriwalilibori:

Как было отмечено , из документации здесь , это , как правило , лучше всего , чтобы импортировать изображения по мере необходимости.

Однако мне нужно было динамически загружать много файлов, что заставило меня поместить изображения в общую папку ( также указанную в README ) из-за этой рекомендации ниже из документации:

Обычно мы рекомендуем импортировать таблицы стилей, изображения и шрифты из JavaScript. Общая папка полезна как обходной путь для ряда менее распространенных случаев:

  • Вам понадобится файл с определенным именем в выводе сборки, например manifest.webmanifest.
  • У вас есть тысячи изображений, и вам необходимо динамически ссылаться на их пути.
  • Вы хотите включить небольшой скрипт, такой как pace.js, вне связанного кода.
  • Некоторая библиотека может быть несовместима с Webpack, и у вас нет другого выхода, кроме как включить ее как тег.

Надеюсь, это поможет кому-то другому! Оставьте мне комментарий, если мне нужно что-то прояснить.


2

Я разрабатываю проект, который использует SSR, и теперь я хочу поделиться своим решением на основе некоторых ответов здесь.

Моя цель - предварительно загрузить изображение, чтобы показывать его при офлайн-подключении к Интернету. (Возможно, это не лучшая практика, но, поскольку это работает для меня, пока все в порядке) К вашему сведению, я также использую ReactHooks в этом проекте.

  useEffect(() => {
    // preload image for offline network
    const ErrorFailedImg = require('../../../../assets/images/error-review-failed.jpg');
    if (typeof window !== 'undefined') {
      new Image().src = ErrorFailedImg;
    }
  }, []);

Чтобы использовать изображение, я пишу его так

<img src="/assets/images/error-review-failed.jpg" />

1

Попробуйте изменить код в server.js на -

app.use(require('webpack-dev-middleware')(compiler, {
      noInfo: true,
      publicPath: config.output.path
    }));

1

Иногда вы можете ввести вместо местоположения изображения / src: попробуйте

./assets/images/picture.jpg

вместо того

../assets/images/picture.jpg

1
src={"/images/resto.png"}

Использование атрибута src таким образом означает, что ваше изображение будет загружено с абсолютного пути "/images/resto.png" для вашего сайта. Каталог изображений должен находиться в корне вашего сайта. Пример: http://www.example.com/images/resto.png


1

Вот что у меня сработало. Во-первых, давайте разберемся с проблемой. Вы не можете использовать переменную как требуемый аргумент. Webpack необходимо знать, какие файлы нужно объединить во время компиляции.

Когда я получил ошибку, я подумал, что это может быть связано с проблемой пути, как в абсолютном и относительном. Поэтому я передал жестко запрограммированное значение, как показано ниже: <img src = {require ("../ assets / images / photosnap.svg")} alt = "" />. Он работал нормально. Но в моем случае значение - это переменная, поступающая из реквизита. Я попытался передать строковую буквальную переменную, как предлагали некоторые. Это не работает. Также я попытался определить локальный метод, используя случай переключения для всех 10 значений (я знал, что это не лучшее решение, но я просто хотел, чтобы оно как-то работало). Это тоже не сработало. Затем я узнал, что мы НЕ можем передавать переменную в require.

В качестве обходного пути я изменил данные в файле data.json, чтобы ограничить их только именем моего изображения. Это имя изображения, полученное из реквизита как строковый литерал. Я соединил его с жестко закодированным значением, например:

import React from "react";

function JobCard(props) {  

  const { logo } = props;
  
  return (
      <div className="jobCards">
          <img src={require(`../assets/images/${logo}`)} alt="" /> 
      </div>
    )
} 
  

Фактическое значение, содержащееся в логотипе, будет происходить из файла data.json и будет относиться к некоторому имени изображения, например photosnap.svg.


0

Лучший способ загрузить локальные изображения в React выглядит следующим образом

Например, храните все свои изображения (или любые ресурсы, такие как видео, шрифты) в общей папке, как показано ниже.

введите описание изображения здесь

Просто напишите, <img src='/assets/images/Call.svg' />чтобы получить доступ к изображению Call.svg из любого вашего компонента реакции

Примечание: хранение ваших ресурсов в общей папке гарантирует, что вы можете получить к ним доступ из любого места из проекта, просто указав '/ path_to_image' и не требуя какого-либо обхода пути '../../', как это


PNG изображение не работает с этим? Bcuz я сделал именно это, и это не сработало.
Maverick,

PNG тоже подойдет. SVG работает на вас? Пожалуйста, проверьте орфографию в имени файла и убедитесь, что путь к изображению правильный.
mokesh moha

1
извиняюсь за эту ошибку. Я был новичком в реакции и не знал, что файл компонента должен начинаться с заглавной буквы. После этого все заработало.
Maverick

0

вы должны сначала импортировать изображение, а затем использовать его. У меня это сработало.


import image from '../image.png'

const Header = () => {
   return (
     <img src={image} alt='image' />
   )
}

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.