<img/> 이미지 경로 설정 - 리액트에서 적절한 상대경로 사용하기

Song·2022년 5월 4일
3
post-thumbnail

creact-react-app으로 리액트 앱을 만들 때 이미지를 쉽게 다룰 수 있는 방법 중 하나가 public/images 폴더 안에 이미지들을 두어 관리하는 방법이다. 이 방법을 사용하는 이유는 '../../../assets/images/sth.png'와 같은 절대 경로를 쓰지 않고 /images/sth.png와 같은 상대 경로를 사용해 같은 소스의 이미지를 불러오도록 하기 위함이다.

이 상대경로를 제대로 설정해주지 않으면 나처럼 이미지 태그의 alt값만 떠있고 도통 이미지는 보이지 않는 슬픈 일이 일어날 수 있다.
alt값만 떠있는 이미지

//파일 - src/assets/images.js
export const loadingImg = {
  //절대경로로 찾아오는 경우임
    loading: "./images/loading.png"
}

이미지를 관리하고 꺼내쓰던 방법은 src/assets/images.js라는 파일에서 객체를 만들어 해당 객체에서 각 이미지 별로 키값을 부여해 public에서 이미지 src를 찾아오도록했다.

이미지를 불러오는 특정 Component.js
import { loadingImg } from '../../assets/images';
...

return (
  <img src={loadingImg.loading} alt={`loading`} />
)

하지만!!!!
위의 코드처럼 썼을때 처음 https://domain.com 홈에서 해당 이미지에 접근할 때는 문제가 없다가, 다른 페이지 (예시: https://domain.com/post/id=sth)에서 똑같은 이미지에 접근하려고 하면 이미지가 깨져서 로딩되는 것이었다.

그래서 개발자도구를 열어 문제가 생긴 이미지의 src를 어떻게 인식하고 있는지를 확인해봤다.

이미지 소스 경로가 잘못된 경우

불러오고 있는 src가 https://localhost:3000/images/loading.png가 되어야지 이미지를 제대로 불러올 수 있는데, 절대경로로 "./images/loading.png"불러왔기 때문에 도메인의 경로가 바뀌는 순간 이미지를 못찾아오는 듯해보였다.

이미지 로딩 실험

// src/assets/images.js
export const loadingImg = {
  //절대경로로 찾아오는 경우임
    loading: "./images/loading.png"
}

//Component.js
import { loadingImg } from '../../assets/images';
import loading from '../../assets/loading.png';

//case1
<img src={loadingImg.loading} alt={`loading`} />
//case2
<img src='/images/loading.png' alt={`loading`} />
//case3
<img src={loading} alt={`loading2`} />

이미지 경로 실험 결과

case2, 3은 모두 정상적으로 이미지를 불러오는 것을 확인할 수 있었다.

개발자 도구를 열어 이미지의 자세한 src를 확인해보면 case2는 상대경로로 바로 이미지를 불러온 것이고,
이미지 상대경로 개발자도구

case3는 직접 png파일이 저장되었는 절대경로로 찾아들어간 것이다.
이미지 절대경로 개발자도구

하지만 case3같은 경우 만약 다른 컴포넌트에서 해당 이미지를 접근하려 한다면 또다시 깨진 이미지를 마주하게 될 가능성이 있다.

case1은 처음부터 이미지가 깨져서 나온다. 아무리 images.js파일에서 이미지가 들어있는 절대경로로 src를 주어도 메인 주소가 바뀌면 해당 이미지를 불러오질 못하기 때문에 문제가 생긴다.

해결방안

나의 경우에는 이미지를 관리하는 src/assets/images.js파일 속 경로를 전부 상대경로로 변경해주었다.

// src/assets/images.js
export const loadingImg = {
  //상대경로로 찾아오기
    loading: "/images/loading.png"
}

위처럼 할 경우 어떤 컴포넌트에서든 loadingImgimport해서 접근할때마다 문제없이 이미지를 불러올 수 있다.
위의 방법말고도 이미지를 불러올때는 public/images 경로에 이미지를 넣어두고 상대경로로 import해오는 것을 강력추천한다.


이와 같은 문제를 겪은 스택오버플로우 질문자에게 감사를 표하면서,,,

https://www.w3schools.com/html/html_filepaths.asp 를 참고하여 더이상 같은 일들이 생기지 않게 파일 경로에 대해 알아두고 넘어간다...
상대경로를 반드시 사용하자!!


추가) 이미지를 상대경로로 import할 경우

이미지가 public/images에 있을 때 이미지를 아래와 같이 불러오고자 한다면,

//error
import logo from "/images/logo.png";
      <img src={logo} alt="Bepol Logo" />
        

이러한 import 에러를 마주할 수 있다.

ERROR in ./src/components/Header.jsx 8:0-36
Module not found: Error: You attempted to import /images/logo.png which falls outside of the project src/ directory. Relative imports outside of src/ are not supported.
You can either move it inside src/, or add a symlink to it from project's node_modules/.

자세히 읽어보면, import는 같은 src 폴더 안에만 있는 것들을 상대경로로 불러올 수 있다고 말해주고 있다.

//good
//import 없애고 바로 src에서 상대경로로 연결
   <img src="/images/logo.png" alt="Bepol Logo" />

이처럼 public/images에 있는 이미지들은 상대경로로 불러오고자 한다면 import할 필요 없이 바로 src에 연결해주면 된다.

0개의 댓글