html, css로 만든 페이지를 React로 바꾸는 실습을 하던 중 img 경로를 설정에서 뒷목잡을 뻔 했다. 보통 src 폴더에 이미지 폴더를 만들고 import를 해서 가져온다. 아마 가장 큰 이유는 컴파일러 단계에서 에러를 잡아주기 때문이라고 생각한다.
하지만 import로 이미지를 가져오면 고정된 경로로 하나의 이미지만 불러져 매번 다른 경로로 불러올 수 없다. (예를 들면 sns 아이콘 이나 로그인 아이콘은 고정적이다. 상품리스트에서 상품 이미지를 받아오는 것은 json 통신을 통해 가져오므로 동적인 경로를 가진다.)
그럼 어떻게 가져오지..?
CRA 문서에서 다음과 같은 경우에만 public 폴더에서 관리하는 것이 유용하고, 이외에는 src 폴더 관리를 추천한다.
- manifest.webmanifest 처럼 build된 결과물에서 특정한 파일 이름이 필요한 경우
- 수천개의 이미지 파일을 동적으로 참조해야 하는 경우
CRA 문서 발췌
여기서 나는 동적으로 이미지를 참고해서 가져와야하는 경우였다.
function Card({ cardInfo }){
const IMG_URL = `../assets/${ cardInfo.cardImg }`;
return(
<div>
<img src={ IMG_URL } alt=''>
<h2>{ cardInfo.cardTitle }</h2>
<div>
)
}
export default function App(){
return(
cardList.map((card)=>(
<Card cardInfo={card}/>
))
)
}
우선 이렇게 코드를 작성하고 확인해보니 잘 나타났다! 동적으로 이미지를 가져와야하는 부분은 위와 같이 작성하고 끝난줄 알았다.
BUT, 이렇게 쉽게 끝났으면 포스팅이 왜 있겠나?
모든 코드를 작성하고 빌드 후 빌드된 url에서 화면을 보는데...
이럴수가 publlic에서 가져온 이미지는 다 깨져서 엑박으로 표시 됬다....
이미지와 관련된 코드를 살펴 보니 package.json
에 추가한
{
"homepage":"github page url",
(생략)
}
homepage url 경로를 설정하면서 웹펙에서 해당 처리가 되지 않았기 때문이였다.
아니 그럼 도대체 어떻게해야 엑박에서 벗어나는가?
위 현상을 해결하기위해 다양한 블로그를 찾아 봤는데, 결국 해결책을 찾은 곳은 리액트 문서였다.
이래서 공식문서부터 꼼꼼히 읽으라고 하는 것 같다.
public폴더에 파일을 넣으면 웹팩에서 처리 되지 않습니다. 대신 빌드 폴더에 그대로 복사됩니다. 폴더 의 자산을 참조하려면 public이라는 환경 변수
PUBLIC_URL
을 사용해야 합니다 .
리액트 공식 문서 中
이렇게 친절히 소개되어있었다. 그 아래에 해결 방법 또한 친절하게 적혀있었다.
index.html
파일에 작성하는 경우<img src="%PUBLIC_URL%/이미지경로/이미지파일.jpg" />
%PUBLIC_URL%
라고 환경변수를 경로에 작성합니다.
<img src={process.env.PUBLIC_URL + '/img/logo.png'} />
process.env.PUBLIC_URL
라고 환경변수를 경로에 작성합니다.
function Card({ cardInfo }){
const IMG_URL = `../assets/${ cardInfo.cardImg }`;
return(
<div>
<img src={ process.env.PUBLIC_URL + '/img/logo.png' } alt=''>
<h2>{ cardInfo.cardTitle }</h2>
<div>
)
}
%PUBLIC_URL%
process.env.PUBLIC_URL