React nie wczytuje lokalnych obrazów

123

Tworzę małą aplikację reagowania, a moje obrazy lokalne się nie ładują. Obrazy jak placehold.it/200x200ładunki. Pomyślałem, że może to może być coś z serwerem?

Oto moja 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')
);

i 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');
});
Petrba
źródło
4
Zwykle oznacza to, że lokalny serwer internetowy nie obsługuje obrazów lub podany adres URL jest nieprawidłowy. Otwórz konsolę przeglądarki i sprawdź, czy nie otrzymujesz żadnych błędów, takich jak 404 nie znaleziono.
Mario Tacke
5
Ludzie! po prostu użyj require(). np. src = {require ("image path")}
Neeraj Sewani

Odpowiedzi:

271

Korzystając z Webpacka, potrzebujesz requireobrazów, aby Webpack mógł je przetworzyć, co wyjaśniałoby, dlaczego obrazy zewnętrzne ładują się, a wewnętrzne nie, więc zamiast tego <img src={"/images/resto.png"} />musisz <img src={require('/images/image-name.png')} />zastąpić image-name.png poprawną nazwą obrazu dla każdego z nich. W ten sposób Webpack może przetwarzać i zastępować źródłowy img.

Tomasz
źródło
1
Ale jak importować wymagają? Browserify? Jeśli tak, to w jaki sposób? Próbowałem import {require} from 'browserify'. Ale to nie działa.
Shubham Kushwah
1
@ShubhamKushwah Nie powinieneś importować require. Jest dostarczany jako część commonjs. Zobacz stackoverflow.com/a/33251937/4103908 i viget.com/articles/gulp-browserify-starter-faq, aby uzyskać dalsze informacje, które mogą pomóc w korzystaniu z require i browserify za pomocą Gulp.
Thomas
@Thomas Problem jest z obrazami wewnętrznymi i zewnętrznymi, nie ładują się przy pierwszym ładowaniu strony, ale jeśli ją odświeżę, załadują się. Jak mam to rozwiązać - proszę o pomoc!
Shubham Kushwah
6
Otrzymuję błąd: Module not found: Error: Can't resolve 'MyPNG.png' in 'C:...\app\components\images'. Ścieżka do pliku wygląda dobrze !.
reubenjohn
2
src = {require ('./ interactLogo.svg')} rozpocznij swoją ścieżkę od „./” dla bieżącego katalogu, aby uniknąć błędów.
cheesey
53

Zacząłem budować swoją aplikację za pomocą aplikacji create-react-app (zobacz zakładkę „Utwórz nową aplikację”). Dołączony plik README.md zawiera następujący przykład:

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;

To zadziałało idealnie dla mnie. Oto link do głównego dokumentu tego README , który wyjaśnia (fragment):

... Możesz zaimportować plik bezpośrednio w module JavaScript. Informuje to Webpack o dołączeniu tego pliku do pakietu. W przeciwieństwie do importu CSS, importowanie pliku daje wartość ciągu. Ta wartość jest ostateczną ścieżką, do której możesz się odwołać w swoim kodzie, np. Jako atrybut src obrazu lub href linku do pliku PDF.

Aby zmniejszyć liczbę żądań kierowanych do serwera, importowanie obrazów o rozmiarze mniejszym niż 10 000 bajtów zwraca identyfikator URI danych zamiast ścieżki. Dotyczy to następujących rozszerzeń plików: bmp, gif, jpg, jpeg i png ...

Hawkeye Parker
źródło
Ponadto musisz także eksportować obrazy skądś, aby móc je importować w dowolnym miejscu, a nie tylko z tego samego katalogu, co miałoby miejsce, gdyby nie były eksportowane. Musiałyby znajdować się w tym samym katalogu, co komponent, do którego były importowane. Zauważysz, że w przypadku każdej nowej aplikacji React utworzonej na przykład za pomocą CRA plik logo.svg znajduje się w tym samym katalogu, co plik App.js, do którego jest importowany. Napisałem artykuł o importowaniu obrazów w React tutaj: blog.hellojs.org/importing-images-in-react-c76f0dfcb552
Maria Campbell
Kontynuując powyższy komentarz, jeśli używasz programu ładującego url pakietu webpack, jak pokazuje fandro, pliki pasujące do rozszerzeń testowych w pakiecie internetowym są automatycznie eksportowane i udostępniane do zaimportowania zapisanego stanu Hawkeye Parker pokazanego powyżej.
dave4jr
Wiem, że to bardzo stary temat, ale nadal; jak to się udało? W moim przypadku program próbuje "odczytać obraz" ... co skutkuje okropnym błędem: Unexpected character '�' (1:0) > 1 | �PNG | ^ 2 | 3 | 4 | IHDR��r~ipHYs���o�d��IDATx^�}���Ü�d7�w¿½ï¿½ ��JzH!�K�ï...
V. Courtois
@ V.Courtois przepraszam - od tamtej pory nie pracowałem z tym materiałem i nie pamiętam teraz żadnych szczegółów :(
Hawkeye Parker
Musiałem dodać moje obrazy do folderu publicznego w projekcie Create-React-App.
piksel 67
29

Inny sposób:

Najpierw należy zainstalować te moduły: url-loader,file-loader

Korzystanie z npm: npm install --save-dev url-loader file-loader

Następnie dodaj to do konfiguracji Webpacka:

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

limit: Limit bajtów do plików wbudowanych jako adres URL danych

Musisz zainstalować oba moduły: url-loaderifile-loader

Wreszcie możesz:

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

Możesz dokładniej zbadać te programy ładujące tutaj:

url-loader: https://www.npmjs.com/package/url-loader

file-loader: https://www.npmjs.com/package/file-loader

fandro
źródło
1
Miejmy nadzieję, że pomoże to innym. Ja też musiałem to zrobić; Zainstaluj program ładujący url. npm install --save-dev url-loader
LUser
1
Zmagałem się z tą wczorajszą nocą, a ten post pojawił się dziś rano na moim ekranie :) Jeśli zobaczysz coś takiego Module build failed: SyntaxError: c:/contrivedpath/images/profile.jpg: Unexpected character '�' (1:0), wszystko, co musisz zrobić, to dodać powyższą konfigurację modułu ładującego url do konfiguracji pakietu webpack, npm install url-loaderAND file-loaderi będziesz być funkcjonalne. Przetestowałem, aby się upewnić, i program ładujący pliki jest konieczny.
agm1984,
1
@ agm1984 Wykonałem powyższe kroki i nadal otrzymuję ERROR in ./src/images/imagename.png Module parse failed: Unexpected character '�' (1:0)wiadomość. Jakieś pomysły?
David
to było naprawdę przydatne, ale nie mogę zrozumieć, dlaczego <img src = "images / myimage.png" /> nie działa !! Czy mógłbyś wyjaśnić?
Mark
Zrobiłem wszystko, co powiedziałeś, ale żadnych kości. Webpack buduje się bez narzekania, widzę, że mój obraz PNG został przeniesiony do katalogu wyjściowego, ale obraz nie ładuje się na stronie. Kiedy sprawdzam kod, po prostu mówię, src=[Object module]a kiedy
najeżdżam
4

Właściwie chciałbym skomentować, ale nie mam jeszcze upoważnienia. To dlatego udaje, że jest następną odpowiedzią, podczas gdy tak nie jest.

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" />;

Chciałbym kontynuować tę drogę. Działa to płynnie, gdy ma się zdjęcie, które można po prostu wstawić. W moim przypadku jest to nieco bardziej złożone: muszę to zmapować kilka zdjęć. Jak dotąd jedyny możliwy sposób, aby to zrobić, jest następujący

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]}/> 

Więc moje pytanie brzmi, czy istnieją prostsze sposoby przetwarzania tych obrazów? Nie trzeba dodawać, że w bardziej ogólnym przypadku liczba plików, które muszą być dosłownie zaimportowane, może być ogromna, podobnie jak liczba kluczy w obiekcie. (Obiekt w tym kodzie zawiera wyraźne odniesienie do nazw-jego kluczy) W moim przypadku procedury związane z wymaganiami nie zadziałały - programy ładujące generowały dziwne błędy podczas instalacji i nie wykazywały śladów działania; i wymaganie samo z siebie też nie zadziałało.

Kiszuriwalilibori
źródło
2

Chciałem tylko zostawić to, co uwydatnia zaakceptowaną powyżej odpowiedź.

Oprócz zaakceptowanej odpowiedzi możesz nieco ułatwić sobie życie, określając aliasścieżkę w programie Webpack, więc nie musisz się martwić, gdzie znajduje się obraz w stosunku do pliku, w którym aktualnie się znajdujesz. Zobacz przykład poniżej :

Plik Webpack:

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

Posługiwać się:

<img src={require("public/img/resto.ong")} />
adamj
źródło
2

Ja również chciałbym dodać do odpowiedzi @Hawkeye Parker i @Kiszuriwalilibori:

Jak odnotowano od docs tutaj , to zazwyczaj najlepiej importować obrazy, ile potrzeba.

Potrzebowałem jednak do dynamicznego ładowania wielu plików, co skłoniło mnie do umieszczenia obrazów w folderze publicznym ( również podanym w README ), z powodu poniższej rekomendacji z dokumentacji:

Zwykle zalecamy importowanie arkuszy stylów, obrazów i czcionek z JavaScript. Folder publiczny jest przydatny jako obejście wielu mniej typowych przypadków:

  • Potrzebujesz pliku o określonej nazwie w danych wyjściowych kompilacji, na przykład manifest.webmanifest.
  • Masz tysiące obrazów i musisz dynamicznie odnosić się do ich ścieżek.
  • Chcesz dołączyć mały skrypt, taki jak pace.js, poza dołączonym kodem.
  • Niektóre biblioteki mogą być niekompatybilne z Webpack i nie masz innego wyjścia, jak tylko dołączyć ją jako tag.

Mam nadzieję, że to pomoże komuś innemu! Zostaw komentarz, jeśli muszę to wyjaśnić.

Vancy-spodnie
źródło
2

Rozwijam projekt wykorzystujący SSR i teraz chcę podzielić się moim rozwiązaniem w oparciu o kilka odpowiedzi tutaj.

Moim celem jest wstępne załadowanie obrazu, aby pokazać go w trybie offline. (Może to nie jest najlepsza praktyka, ale ponieważ to działa, na razie jest w porządku) FYI, również używam ReactHooks w tym projekcie.

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

Aby użyć obrazu, piszę to w ten sposób

<img src="/assets/images/error-review-failed.jpg" />
Vinsensius Danny
źródło
1

Spróbuj zmienić kod w server.js na -

app.use(require('webpack-dev-middleware')(compiler, {
      noInfo: true,
      publicPath: config.output.path
    }));
niebezpieczny
źródło
1

Czasami możesz wpisać zamiast w lokalizacji obrazu / src: try

./assets/images/picture.jpg

zamiast

../assets/images/picture.jpg
Kean Amaral
źródło
1
src={"/images/resto.png"}

Użycie atrybutu src w ten sposób oznacza, że ​​obraz zostanie załadowany z bezwzględnej ścieżki „/images/resto.png” Twojej witryny. Katalog obrazów powinien znajdować się w katalogu głównym witryny. Przykład: http://www.example.com/images/resto.png

zdrsoft
źródło
1

Oto, co zadziałało dla mnie. Najpierw zrozumiemy problem. Nie możesz użyć zmiennej jako argumentu do wymagania. Webpack musi wiedzieć, jakie pliki mają być pakowane w czasie kompilacji.

Kiedy otrzymałem błąd, pomyślałem, że może to być związane z problemem ścieżki, tak jak w przypadku wartości bezwzględnej i względnej. Więc przekazałem zakodowaną wartość, aby wymagać, jak poniżej: <img src = {require ("../ asset / images / photosnap.svg")} alt = "" />. Działało dobrze. Ale w moim przypadku wartość jest zmienną pochodzącą z rekwizytów. Próbowałem przekazać zmienną literału ciągu, jak niektórzy sugerowali. To nie działało. Próbowałem też zdefiniować metodę lokalną za pomocą przełącznika dla wszystkich 10 wartości (wiedziałem, że to nie jest najlepsze rozwiązanie, ale po prostu chciałem, aby jakoś działało). To też nie zadziałało. Wtedy dowiedziałem się, że NIE możemy przekazać zmiennej do żądania.

Aby obejść ten problem, zmodyfikowałem dane w pliku data.json, aby ograniczyć je tylko do nazwy mojego obrazu. Ta nazwa obrazu, która pochodzi z rekwizytów jako literał String. Połączyłem go z zakodowaną wartością, na przykład:

import React from "react";

function JobCard(props) {  

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

Rzeczywista wartość zawarta w logo pochodziłaby z pliku data.json i odnosiłaby się do nazwy obrazu, na przykład photosnap.svg.

Venky4c
źródło
0

Najlepszy sposób na załadowanie lokalnych obrazów w reakcji jest następujący

Na przykład zachowaj wszystkie swoje obrazy (lub wszelkie zasoby, takie jak filmy, czcionki) w folderze publicznym, jak pokazano poniżej.

wprowadź opis obrazu tutaj

Po prostu napisz, <img src='/assets/images/Call.svg' />aby uzyskać dostęp do obrazu Call.svg z dowolnego komponentu reagowania

Uwaga: przechowywanie zasobów w folderze publicznym zapewnia, że ​​można uzyskać do nich dostęp z dowolnego miejsca w projekcie, po prostu podając „/ path_to_image” i nie ma potrzeby przechodzenia przez ścieżkę „../../” w ten sposób

mokesh moha
źródło
Obraz PNG nie zadziała na tym? Ponieważ zrobiłem dokładnie to i nie zadziałało.
maverick
PNG również będzie działać. Czy SVG działa dla Ciebie? Sprawdź pisownię w nazwie pliku i upewnij się, że ścieżka obrazu jest poprawna.
mokesh moha
1
przepraszam za ten błąd. Byłem nowy w reagowaniu i nie wiedziałem, że plik komponentu powinien zaczynać się od wielkości liter. Potem zadziałało.
Maverick
0

musisz najpierw zaimportować obraz, a następnie go użyć. U mnie to zadziałało.


import image from '../image.png'

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

Omama Zainab
źródło