React não carrega imagens locais

123

Estou construindo um pequeno aplicativo de reação e minhas imagens locais não carregam. Imagens como placehold.it/200x200cargas. Eu pensei que talvez pudesse ser algo com o servidor?

Aqui está meu 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')
);

e 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
fonte
4
Isso geralmente significa que o servidor da web local não está servindo as imagens ou o url que você especificou está incorreto. Abra o console do navegador e verifique se você recebe algum erro, como 404 não encontrado.
Mario Tacke
5
Pessoal! apenas use require(). por exemplo, src = {require ("image path")}
Neeraj Sewani

Respostas:

268

Ao usar o Webpack, você precisa das requireimagens para que o Webpack as processe, o que explicaria por que as imagens externas carregam enquanto as internas não, então, em vez de <img src={"/images/resto.png"} />usar a <img src={require('/images/image-name.png')} />substituição de image-name.png pelo nome de imagem correto para cada uma delas. Dessa forma, o Webpack é capaz de processar e substituir o img de origem.

Thomas
fonte
1
Mas como importar exigir? Browserify? Se sim, como? Eu tentei import {require} from 'browserify'. Mas não está funcionando.
Shubham Kushwah
1
@ShubhamKushwah Você não deve ter que importar require. Ele é fornecido como parte de commonjs. Consulte stackoverflow.com/a/33251937/4103908 e viget.com/articles/gulp-browserify-starter-faq para obter mais detalhes que podem ajudá-lo a usar o require e o browserify usando o Gulp.
Thomas
@Thomas O problema é com as imagens internas e externas, elas não carregam quando a página é carregada pela primeira vez, mas se eu atualizá-la, elas carregarão. Então, como devo resolver isso - Por favor, ajude!
Shubham Kushwah
6
Recebendo um erro: Module not found: Error: Can't resolve 'MyPNG.png' in 'C:...\app\components\images'. O caminho para o arquivo parece bom !.
reubenjohn
2
src = {require ('./ reactLogo.svg')} inicie seu caminho com "./" para o diretório atual para evitar erros.
cheesey
53

Comecei a construir meu aplicativo com create-react-app (consulte a guia "Criar um novo aplicativo"). O README.md que o acompanha dá este exemplo:

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;

Isso funcionou perfeitamente para mim. Aqui está um link para o documento mestre desse README , que explica (trecho):

... Você pode importar um arquivo diretamente em um módulo JavaScript. Isso informa ao Webpack para incluir esse arquivo no pacote. Ao contrário das importações CSS, importar um arquivo fornece um valor de string. Este valor é o caminho final que você pode fazer referência em seu código, por exemplo, como o atributo src de uma imagem ou o href de um link para um PDF.

Para reduzir o número de solicitações ao servidor, a importação de imagens com menos de 10.000 bytes retorna um URI de dados em vez de um caminho. Isso se aplica às seguintes extensões de arquivo: bmp, gif, jpg, jpeg e png ...

Hawkeye Parker
fonte
Além disso, você também deve exportar as imagens de algum lugar para poder importá-las de qualquer lugar e não apenas de dentro do mesmo diretório, o que seria o caso se não estivessem sendo exportadas. Eles teriam que residir no mesmo diretório do componente para o qual estavam sendo importados. Você notará que com qualquer novo aplicativo React criado com CRA, por exemplo, o arquivo logo.svg reside no mesmo diretório que App.js, para onde é importado. Escrevi um artigo sobre importação de imagens no React aqui: blog.hellojs.org/importing-images-in-react-c76f0dfcb552
Maria Campbell
Para acompanhar o comentário acima, se você usar o webpack url-loader como fandro mostra acima, seus arquivos que correspondem às extensões de teste no webpack são automaticamente exportados e disponibilizados para importar o salvamento que Hawkeye Parker mostrou acima.
dave4jr
Eu sei que este é um assunto muito antigo, mas ainda assim; como você fez isso funcionar? No meu caso, o programa está tentando "ler a imagem" ... resultando em um erro terrível: Unexpected character '�' (1:0) > 1 | �PNG | ^ 2 | 3 | 4 | IHDR��r~ipHYs���o�d��IDATx^�}���Ü�d7�w¿½ï¿½ ��JzH!�K�ï...
V. Courtois
@ V.Courtois desculpe - não trabalhei com essas coisas desde então e não me lembro de mais detalhes agora :(
Hawkeye Parker
Tive que adicionar minhas imagens à pasta pública no projeto Create-React-App.
pixel 67 de
29

Outra maneira de fazer:

Em primeiro lugar, instalar esses módulos: url-loader,file-loader

Usando npm: npm install --save-dev url-loader file-loader

Em seguida, adicione à sua configuração do Webpack:

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

limit: Limite de bytes para arquivos embutidos como URL de dados

Você precisa instalar os dois módulos: url-loaderefile-loader

Finalmente, você pode fazer:

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

Você pode investigar esses carregadores mais aqui:

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

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

fandro
fonte
1
Espero que ajude outros. Eu tinha que fazer isso também; Instale o url-loader. npm install --save-dev url-loader
LUser
1
Eu estava lutando com isso ontem à noite, e este post estava na minha tela esta manhã :) Se você Module build failed: SyntaxError: c:/contrivedpath/images/profile.jpg: Unexpected character '�' (1:0)vir algo como , tudo o que você precisa fazer é adicionar esta configuração do url-loader acima à configuração do seu webpack, npm install url-loaderE file-loadere você irá ser funcional. Eu testei para ter certeza, e o carregador de arquivos é necessário.
agm1984
1
@ agm1984 Eu segui os passos acima e ainda estou recebendo a ERROR in ./src/images/imagename.png Module parse failed: Unexpected character '�' (1:0)mensagem. Alguma ideia?
David
foi muito útil, mas não consigo entender por que <img src = "images / myimage.png" /> não funciona !! Você poderia explicar?
Marcos
Fez tudo que você disse, mas sem dados. O Webpack constrói sem reclamar, posso ver que minha imagem PNG foi movida para o diretório de saída, mas a imagem não carrega na página. Quando inspeciono o código, ele apenas diz src=[Object module]e quando passo o mouse, ele diz 'não foi possível carregar a imagem'
JSStuball
4

Na verdade gostaria de comentar, mas ainda não estou autorizado. É por isso que fingir ser a próxima resposta enquanto não é.

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

Eu gostaria de continuar nesse caminho. Isso funciona bem quando se tem uma imagem que pode ser inserida com facilidade. No meu caso isso é um pouco mais complexo: tenho que mapear várias fotos. Até agora, a única maneira viável de fazer isso que encontrei é a seguinte

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

Então, minha pergunta é se existem maneiras mais simples de processar essas imagens? Nem é preciso dizer que, em casos mais gerais, o número de arquivos que devem ser importados literalmente pode ser enorme e o número de chaves no objeto também. (O objeto nesse código está envolvido claramente para se referir por nomes - suas chaves) No meu caso, os procedimentos relacionados à solicitação não funcionaram - os carregadores geraram erros de tipo estranho durante a instalação e não mostraram nenhuma marca de funcionamento; e exigir por si só não funcionou.

Kiszuriwalilibori
fonte
2

Eu só queria deixar o seguinte, o que reforça a resposta aceita acima.

Além da resposta aceita, você pode tornar sua vida um pouco mais fácil especificando um aliascaminho no Webpack, para que não precise se preocupar onde a imagem está localizada em relação ao arquivo em que você está no momento. Veja o exemplo abaixo :

Arquivo Webpack:

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

Usar:

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

Eu também gostaria de acrescentar às respostas de @Hawkeye Parker e @Kiszuriwalilibori:

Como foi observado nos documentos aqui , normalmente é melhor importar as imagens conforme necessário.

Porém, muitos arquivos precisavam ser carregados dinamicamente, o que me levou a colocar as imagens na pasta pública ( também declarado no README ), devido a esta recomendação abaixo da documentação:

Normalmente, recomendamos importar folhas de estilo, imagens e fontes do JavaScript. A pasta pública é útil como solução alternativa para alguns casos menos comuns:

  • Você precisa de um arquivo com um nome específico na saída da compilação, como manifest.webmanifest.
  • Você tem milhares de imagens e precisa referenciar dinamicamente seus caminhos.
  • Você deseja incluir um pequeno script como pace.js fora do código empacotado.
  • Algumas bibliotecas podem ser incompatíveis com o Webpack e você não tem outra opção a não ser incluí-las como uma tag.

Espero que ajude mais alguém! Deixe-me um comentário se eu precisar esclarecer qualquer coisa.

calça vancy
fonte
2

Estou desenvolvendo um projeto que utiliza SSR e agora quero compartilhar minha solução com base em algumas respostas aqui.

Meu objetivo é pré-carregar uma imagem para mostrá-la quando a conexão com a Internet estiver offline. (Pode não ser a melhor prática, mas como funciona para mim, por enquanto está tudo bem) Para sua informação, também uso ReactHooks neste projeto.

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

Para usar a imagem, eu escrevo assim

<img src="/assets/images/error-review-failed.jpg" />
Vinsensius Danny
fonte
1

Tente alterar o código em server.js para -

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

Às vezes, você pode inserir em vez de em sua localização de imagem / src: try

./assets/images/picture.jpg

ao invés de

../assets/images/picture.jpg
Kean Amaral
fonte
1
src={"/images/resto.png"}

Usar o atributo src desta forma significa que sua imagem será carregada do caminho absoluto "/images/resto.png" para seu site. O diretório de imagens deve estar localizado na raiz do seu site. Exemplo: http://www.example.com/images/resto.png

zdrsoft
fonte
1

Aqui está o que funcionou para mim. Primeiro, vamos entender o problema. Você não pode usar uma variável como argumento para requerer. O Webpack precisa saber quais arquivos empacotar no momento da compilação.

Quando recebi o erro, pensei que poderia estar relacionado ao problema do caminho como em absoluto vs relativo. Então, passei um valor embutido em código para exigir como abaixo: <img src = {require ("../ assets / images / photosnap.svg")} alt = "" />. Estava funcionando bem. Mas, no meu caso, o valor é uma variável vinda dos adereços. Tentei passar uma variável literal de string como alguns sugeriram. Não funcionou. Também tentei definir um método local usando switch case para todos os 10 valores (eu sabia que não era a melhor solução, mas queria que funcionasse de alguma forma). Isso também não funcionou. Então descobri que NÃO podemos passar variáveis ​​para o require.

Como solução alternativa, modifiquei os dados no arquivo data.json para restringi-los apenas ao nome da minha imagem. Este nome de imagem que vem dos adereços como um literal de string. Eu concatenei-o com o valor codificado, assim:

import React from "react";

function JobCard(props) {  

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

O valor real contido no logotipo viria do arquivo data.json e se referiria a algum nome de imagem como photosnap.svg.

Venky4c
fonte
0

A melhor maneira de carregar imagens locais no react é a seguinte

Por exemplo, mantenha todas as suas imagens (ou quaisquer recursos como vídeos, fontes) na pasta pública conforme mostrado abaixo.

insira a descrição da imagem aqui

Basta escrever <img src='/assets/images/Call.svg' />para acessar a imagem Call.svg de qualquer um de seus componentes react

Observação: manter seus ativos na pasta pública garante que você possa acessá-los de qualquer lugar do projeto, apenas fornecendo '/ path_to_image' e sem a necessidade de qualquer percurso de caminho '../../' como este

mokesh moha
fonte
Imagem PNG não vai funcionar nisso? Porque eu fiz exatamente isso e não funcionou.
maverick
PNG também funcionará. O SVG está funcionando para você? Faça a verificação ortográfica do nome do arquivo e certifique-se de que o caminho da imagem está correto.
mokesh moha
1
desculpas por este erro. Eu era novo em reagir e não sabia que o arquivo do componente deveria começar com maiúsculas. Depois disso funcionou.
maverick
0

você deve importar a imagem primeiro e depois usá-la. Funcionou para mim


import image from '../image.png'

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

Omama Zainab
fonte