ปฏิกิริยาจะไม่โหลดภาพในเครื่อง


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;

ดัชนี 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
Mario Tacke

5
คน! เพียงแค่ใช้require(). เช่น src = {ต้องใช้ ("image path")}
Neeraj Sewani

เพียงแค่ใช้ 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สำหรับรายละเอียดเพิ่มเติมที่อาจช่วยให้คุณใช้ need และ browserify โดยใช้ Gulp
โทมัส

@ โทมัสปัญหาเกิดจากภาพภายในและภายนอกภาพจะไม่โหลดเมื่อโหลดหน้าแรก แต่ถ้าฉันรีเฟรชมันจะโหลด ฉันจะแก้ปัญหานี้อย่างไร - โปรดช่วยด้วย!
Shubham Kushwah

6
รับข้อผิดพลาด: Module not found: Error: Can't resolve 'MyPNG.png' in 'C:...\app\components\images'. เส้นทางไปยังไฟล์ดูดี!.
reubenjohn

2
src = {require ('./ reactLogo.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
Maria Campbell

หากต้องการติดตามความคิดเห็นด้านบนหากคุณใช้ webpack url-loader ตามที่ fandro แสดงไว้ข้างต้นไฟล์ของคุณที่ตรงกับส่วนขยายการทดสอบใน webpack จะถูกส่งออกโดยอัตโนมัติและทำให้สามารถนำเข้าบันทึก Hawkeye Parker ที่แสดงไว้ด้านบนได้
dave4jr

ฉันรู้ว่านี่เป็นหัวข้อเก่าจริงๆ แต่ก็ยัง; คุณทำงานอย่างไร ในกรณีของฉันโปรแกรมพยายาม "อ่านภาพ" ... ส่งผลให้เกิดข้อผิดพลาดที่น่ากลัว: Unexpected character '�' (1:0) > 1 | �PNG | ^ 2 | 3 | 4 | IHDR��r~ipHYs���o�d��IDATx^�}���Ü�d7�w¿½ï¿½ ��JzH!�K�ï...
V. Courtois

@ V.Courtois ขอโทษ - ฉันไม่ได้ทำงานกับสิ่งนี้ตั้งแต่นั้นมาและฉันจำรายละเอียดเพิ่มเติมไม่ได้ในตอนนี้ :(
Hawkeye Parker

ฉันต้องเพิ่มรูปภาพของฉันไปยังโฟลเดอร์สาธารณะในโครงการ Create-React-App
พิกเซล 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-loader: https://www.npmjs.com/package/url-loader

ตัวโหลดไฟล์: https://www.npmjs.com/package/file-loader


1
หวังว่ามันจะช่วยคนอื่น ๆ ฉันก็ต้องทำเช่นนี้เช่นกัน ติดตั้ง url-loader npm install --save-dev url-loader
LUser

1
ฉันกำลังต่อสู้กับคืนที่ผ่านมานี้และโพสต์นี้เป็นจริงบนหน้าจอของฉันเช้านี้ :) ถ้าคุณเห็นสิ่งที่ชอบModule build failed: SyntaxError: c:/contrivedpath/images/profile.jpg: Unexpected character '�' (1:0)สิ่งที่คุณต้องทำคือการเพิ่มการตั้งค่านี้ URL โหลดด้านบนเพื่อกำหนดค่า 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
  • คุณมีภาพหลายพันภาพและจำเป็นต้องอ้างอิงเส้นทางของพวกเขาแบบไดนามิก
  • คุณต้องการรวมสคริปต์ขนาดเล็กเช่นก้าว js นอกโค้ดบันเดิล
  • ไลบรารีบางแห่งอาจเข้ากันไม่ได้กับ Webpack และคุณไม่มีตัวเลือกอื่นนอกจากรวมไว้เป็นแท็ก

หวังว่าจะช่วยคนอื่น! แสดงความคิดเห็นหากฉันต้องการล้างข้อมูลใด ๆ


2

ฉันกำลังพัฒนาโครงการที่ใช้ SSR และตอนนี้ฉันต้องการแบ่งปันวิธีการแก้ปัญหาของฉันตามคำตอบบางส่วนที่นี่

เป้าหมายของฉันคือโหลดรูปภาพล่วงหน้าเพื่อแสดงเมื่อเชื่อมต่ออินเทอร์เน็ตแบบออฟไลน์ (อาจไม่ใช่แนวทางปฏิบัติที่ดีที่สุด แต่เนื่องจากมันใช้ได้ผลสำหรับฉันตอนนี้ก็โอเค) FYI ฉันใช้ 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

บางครั้งคุณอาจป้อนแทนในตำแหน่งรูปภาพของคุณ / 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 ค่า (ฉันรู้ว่ามันไม่ใช่ทางออกที่ดีที่สุด แต่ฉันแค่อยากให้มันทำงานอย่างใด) ก็ไม่ได้ผลเช่นกัน จากนั้นฉันก็รู้ว่าเราไม่สามารถส่งผ่านตัวแปรไปยังความต้องการได้

วิธีแก้ปัญหาชั่วคราวฉันได้แก้ไขข้อมูลในไฟล์ data.json เพื่อ จำกัด ให้เป็นเพียงชื่อรูปภาพของฉัน ชื่อภาพที่มาจากอุปกรณ์ประกอบฉากนี้เป็น String literal ฉันเชื่อมต่อกับค่าฮาร์ดโค้ดดังนี้:

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

วิธีที่ดีที่สุดในการโหลดภาพในเครื่องในการตอบกลับมีดังนี้

ตัวอย่างเช่นเก็บภาพทั้งหมดของคุณ (หรือเนื้อหาใด ๆ เช่นวิดีโอแบบอักษร) ไว้ในโฟลเดอร์สาธารณะดังที่แสดงด้านล่าง

ใส่คำอธิบายภาพที่นี่

เพียงเขียน<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' />
   )
}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.