프로젝트/리뷰노트

[트러블 슈팅] Netlify 배포하기 : 이미지 에셋 불러오기, Page Not Found 오류 해결

알파카털파카 2024. 8. 19. 02:34
[트러블 슈팅] 
Netlify 배포하기 : 이미지 에셋 불러오기, Page Not Found 오류 해결

 

 

새로운 사이드 프로젝트를 시작했다. 백엔드 API가 준비되고 기능을 본격적으로 구현하기 전에, 기본적인 페이지 라우터 구성과 UI를 보여줄 수 있도록 데모 버전 사이트를 배포하기로 했다. Netlify로 간단하게 배포를 하고, 배포 후에 문제점들을 찾아 해결해나간 과정을 담아보았다.

 

⚙️ Netlify로 배포하기
  - 처음 배포한 사이트에서 문제 정의하기
🧩 이미지 에셋 깨짐 오류
🚨 Page Not Found 오류
🙆🏻‍♀️ 문제 해결 후 Netlify 살펴보기
💛 마치며

 

 


 

 

Netlify로 배포하기

최근에 리액트가 버셀과 공식적으로 협력을 많이 하고 있기 때문에 Vercel로 배포하고 싶었으나, 나의 프로젝트는 팀 조직에 속해있었다. 그럴 경우에는 구독해서 사용해야 한다길래 차선책으로 Netlify를 떠올렸다.

 

Netlify는 팀 조직의 레포지토리여도 무료로 사용할 수 있었다. 예전에 써보기도 했고 편한 점도 있으니 잘 됐다.

Vercel의 구독 요구🥲

 

 

처음 배포한 사이트에서 문제 정의하기

몇 번의 빌드 실패 끝에 최종으로 오류를 다 해결하고 첫번째로 배포된 사이트를 기대에 차서 열었다. 그렇지만... 더보기

 

우선 이미지가 다 깨져있었다. 오른쪽 스크린샷(완성본)처럼 로고와 아이콘이 나와야 하는데 alt의 내용만 나오고 있다. 

(좌) 처음 배포된 사이트, (우) 개선 후 사이트

 

다른 페이지는 어떤가 싶어 url을 변경했는데 라우터가 제대로 동작하지 않는다.

Page Not Found라는 오류창이 뜨고 Netlify의 서포트 가이드를 살펴보도록 안내하고 있다. 

 

Page Not Found

 

공식 서포트 가이드

 

그렇다면 당장 정의할 수 있는 문제는 아래의 두 가지다. 

  1. 이미지 깨짐
  2. 라우터가 제대로 동작하지 않음

이 둘을 해결하는 방법을 알아보자. 

 

배포 중 미니게임

 

참고로 netlify는 배포 중 지루함을 달래라고 미니게임도 준비되어 있다. 카드 짝 맞추기 게임인데 배포가 제대로 안 될까봐 초조해서 게임에 집중할 겨를이 없었다.

 

 

 

 

이미지 에셋 깨짐 오류

배포된 사이트의 콘솔에 뜨는 메세지는 이랬다. 404 오류와 함께 이미지 파일의 경로를 제대로 찾지 못해서 이미지가 깨져보였던 것이다. 

GET https://사이트주소.netlify.app/src/assets/logo.svg 404 (Not Found) logo.svg:1 

 

기존에 /src안에 있던 assets 폴더를 public 디렉토리로 옯겼다. 

 

src 디렉토리 내의 파일은 빌드 시에 번들링되어 배포에 사용되는 파일로 합쳐진다. 이런 파일에는 직접 접근하기 어려우므로, src 디렉토리 내의 이미지를 참조하려면 import해서 불러와야 한다. vite, webpack 등의 번들러가 이미지 파일을 번들에 포함하도록 하는 것이다.

 

빌드는 src 디렉토리 내의 파일을 최적화하고 번들링해서 배포 가능한 형태로 만드는 것이다. public 디렉토리의 파일은 빌드 시에 별도의 변환 없이 그대로 최종 빌드 결과물에 포함된다. 그렇기 때문에 public 디렉토리의 파일은 직접 접근이 가능하다. 서버에서도 유저가 요청한 URL에 따라 이미지 등이 제공된다.

 

나는 이미지 에셋을 public 디렉토리로 이동시켜서, 빌드 과정에서 그대로 복사되어 빌드 디렉토리에 포함되도록 했다.

 

(좌) 처음 배포된 사이트의 디렉토리, (우) 개선 후 디렉토리

 

이미지를 사용하는 곳에서도 코드를 수정했다. 

 

// 기존
<img src="/src/assets/logo.svg" alt="로고" />

// src 디렉토리의 이미지 에셋을 import로 불러올 경우
import logo from './assets/logo.svg';

<img src={logo} alt="로고" />

// public 폴더로 이동 후
<img src="/assets/logo.svg" alt="로고" /> ✅

 

 

 

 

Page Not Found 오류

페이지 url을 전환할 때 오류가 발생했다. 이는 리다이렉션이 제대로 되고있지 않기 때문이다. 

 

배포 후 디테일 페이지에서는 Netlify의 Deploy Summary를 볼 수 있다. 여기서는 배포에 관한 정보가 요약되어 있다. 업로드된 파일의 갯수, 사이트 헤더와 리다이렉션의 상태, 배포된 함수와 엣지 함수 등을 알려준다. 

 

처음 배포한 사이트의 배포 요약에서는 'No redirect rules processed'라고 적혀있었다. 나는 따로 리다이렉트 설정을 한 적이 없으므로 당연한 결과였다. 이 경우 배포된 사이트에서 Page Not Found를 보게 된다. 

 

기존 배포 요약

 

그러면 공식문서에 따라 _redirects 파일을 만들어 해결해보자. 

 

Redirects and rewrites

Manage traffic to your site by defining redirect or rewrite rules in a _redirects file or a netlify.toml file.

docs.netlify.com

 

공식 문서 - 리다이렉션

 

공식 문서 - 리다이렉션 파일 작성하기

 

확장자 없는 _redirects 파일을 public 디렉토리에 생성한다. 나는 vite와 react, typescript를 사용해 프로젝트를 진행하고 있다. 내 프로젝트는 SPA 방식으로 렌더링된다. '싱글 페이지' 어플리케이션이기 때문에 매번 새로운 페이지를 렌더링하지 않고, index.html 파일만 불러오면 자바스크립트에서 페이지 전환에 필요한 영역만 다시 렌더링한다. 그래서 _redirects 파일에 입력할 내용이 한 줄 뿐이다. 이는 프레임워크마다 차이가 있으므로 공식문서를 잘 살펴봐야 한다. 

 

# _redirects 파일

/* /index.html 200

 

/* 모든 경로를 /index.html로 리다이렉트하고 상태코드 200을 반환한다는 의미이다. 

 

SPA의 클라이언트에서 처리해야하는 라우터 요청을 netlify의 서버에서 하고 있기 때문에 문제가 된 것이다. _redirects 파일을 추가하면 배포 사이트에서 페이지 이동 요청이 생겼을 때 리액트 라우터가 처리하게 된다.

 

netlify의 redirect engine은 _redirects, netlify.toml 파일 등을 통해 구성된다. 따라서 이 파일에 리다이렉트 규칙을 정해두면 사이트의 URL을 자동으로 전환시켜준다.

 

개선 후 배포 요약

 

개선 후 새로 배포하니, 배포 요약에 하나의 리다이렉트 룰이 생겼다.

 

 

 

 

문제 해결 후 Netlify 살펴보기

기존 배포
개선 후 배포

 

제대로 배포를 하고 나서 기존의 문제가 있던 배포와, 개선 후의 배포를 살펴보았다. 해결할 문제는 이미지 깨짐 이슈와 라우터 이슈 2가지였다. 

 

이미지를 불러오지 못하는 이슈는 이미지 경로를 변경하고 해결됐다. assets 디렉토리의 파일 갯수를 살펴보면 차이가 있다. 2개에서 34개로 늘었다. 이미지 에셋이 추가되어 아이콘이 깨지는 일 없어 잘 불러와진다.

 

페이지를 찾지 못하는 이슈는 _redirects 파일을 추가하고 해결됐다. _redirects 파일에서 라우터 설정을 했기 때문에 페이지 이동 문제도, Page Not Found 창도 없어졌다. 

 

 

 

마치며

프론트엔드 개발자가 어디까지 알아야 하는가? 시작부터 끝까지! 예전에 그 말을 들었을 때는 신경쓸 부분이 너무 많지 않나 생각했다. 그렇지만 이제는 배포도 뚝딱뚝딱 해나가고 있다. 다음엔 vercel로도 시도해볼 기회가 있으면 좋겠다. 이번에 배포한 netlify 사이트는 UI를 확인하기 위한 데모 버전이라 API를 이용한 기능은 작동하지 않는다. 그래서 가벼운 마음으로 netlify를 이용해 배포를 시도했으나 작은(?) 트러블 슈팅이 있었다. 이번 프로젝트를 완성하고 본격적으로 배포할 날이 기다려진다.