Warm tip: This article is reproduced from serverfault.com, please click

Issue trying to load image from json path in CRA app

发布于 2020-11-29 13:04:29

I'm unable to load images from src/assets/image in my CRA app. I'm trying to avoid putting these images in my public folder but for some reason that seems to be the only way they will be displayed.

I have a json file homepageinfo.ts with a path

export const homepageinfo: homepageinfoType = {
  ...
  hero_portrait: "testimg.jpg",
};

A util function file dataClient to import json files with the function getHomePageInfo.

export const getHomePageInfo = () => {
  return homepageinfo;
};

and another file HomeTitle.tsx

import React from "react";
import { Grid, Header, Image, Segment } from "semantic-ui-react";
import { getHomePageInfo } from "utils/dataClient";

export const HomeTitle = () => {
  let homepageinfo = getHomePageInfo();

  return (
    <Grid columns={2}>
      ...
      <Grid.Column
        only="tablet computer"
        verticalAlign="bottom"
        textAlign="right"
      >
        {console.log(require("assets/image/" + homepageinfo.hero_portrait))}
        <Image as="img"
          className="img_portrait"
          spaced={"left"}
          src={require("assets/image/" + homepageinfo.hero_portrait)}
        />
      </Grid.Column>
    </Grid>
  );
};

The console.log is able to return a value for assets/image/homepageinfo.hero_portrait however it still appears blank in the actual Image component.

Image of a blank component and a console output from Firefox

If I move the image to the public folder it can display but I do not want to have to put these images inside of the public folder.

Questioner
nullmage
Viewed
0
Vitalii 2020-11-29 21:46:18

You need default from result returned by require().

This is usually handled for you when import statement is used instead of require()

import React from "react";
import { Grid, Header, Image, Segment } from "semantic-ui-react";
import { getHomePageInfo } from "utils/dataClient";

export const HomeTitle = () => {
  let homepageinfo = getHomePageInfo();
  let imageUrl;
  try {
    const res = require("assets/image/" + homepageinfo.hero_portrait);
    console.log(res);
    imageUrl = res.default;
  } catch () {
    imageUrl = ''; // file not found
  }

  return (
    <Grid columns={2}>
      ...
      <Grid.Column
        only="tablet computer"
        verticalAlign="bottom"
        textAlign="right"
      >
        <Image as="img"
          className="img_portrait"
          spaced={"left"}
          src={imageUrl}
        />
      </Grid.Column>
    </Grid>
  );
};

UPDATED require() may fail if the file is not found.

So I'd recommend using import as documentation suggests like this:

homepageinfo.ts:

import testImg from './assets/image/testimg.jpg';

export const homepageinfo: homepageinfoType = {
  ...
  hero_portrait: testImg,
};

This way all images will be resolved to paths during build time and homepageinfo.hero_portrait will contain the resulting URL