문제는 제 포트폴리오 사이트를 배포하며 일어났습니다.
나를 나타낼 수 있는 포트폴리오를 만들어보기로 한지 한달 반이 넘었고 결국 완성한 포트폴리오 사이트를 github에서 제공하는 github 페이지를 이용해 정적 호스팅 하기로 결정했습니다!!
처음 github 페이지를 이용하다보니 이것저것 셋팅하는데 시간이 제법 걸렸지만 성공적으로 배포를 했고 두근대며 확인한 결과!!
그렇습니다..404 에러가 발생했습니다..
아니, 정확히는 개발할때는 멀쩡했던 image 파일들이 모두 404 에러를 뱉고있었습니다.
이제껏 배포를 하며 수 많은 경로 문제를 겪었던 저였기에 쉽게 해결할 수 있을거라 생각했지만 쉽게 해결되지 않았습니다..
사실 정적호스팅, 그러니까 nuxt3 기준 npx nuxi generate 혹은 npm run generate 명령어를 사용해 얻은 빌드 결과를 배포해보는건 처음이라 더 막혔던 것 같습니다...(변명이고 그냥 제가 Nuxt 공부 대충 해서 그런거겠죠..ㅋㅋ)
문제의 404 에러
우선 위 첨부한 이미지와 같은 에러가 무수히 발생했습니다.
저는 현재 Nuxt에서 자체적으로 제공하는 이미지 최적화 컴포넌트인
NuxtImg 를 통해서 로컬 이미지를 보여주고 있었는데 이것이 화근이었습니다.
NuxtImg는 Nuxt Image용 내장 및 자체 호스팅 이미지 최적화 프로그램인 ipx를 통해 이미지를 보여주는데
관련 설정을 제가 잘못했을거라 생각하고 구글링해보니 이미 많은 사람들이 정적 호스팅시에 NuxtImg 사용에서의 경로 문제를 겪고 있었고 여러 해결방법들을 제시하고 있었습니다!
그 중 효과 있었던 방법에 대해서만 서술하겠습니다
1. NuxtConfig의 nitro 옵션을 통한 Pre-rendering
부족한 지식으로나마 추측해보기로는
NuxtImg의 ipx 프로그램은 노드 환경에서 돌아가는 것 같습니다.
하지만 generate시 노드 위에서 운영되지 않는 정적 사이트가 구축되기에 ipx를 사용하지 못하게 됩니다.
이런 환경이지만 NuxtImg는 계속해서 ipx를 통해서 이미지 경로를 얻으려고 시도하기에 문제의 404 에러가 발생한다는 결론을 내렸습니다.
https://image.nuxt.com/advanced/static-images
공문에 따르면
"정적사이트 구축을 위해 서버 사이드 옵션을 비활성화(ssr:false) 하면 NuxtImg는 이미지를 가지고 올 수 없다고 합니다.
그래서 nitro 옵션을 통한 이미지 Pre-render를 사용하면 해결할 수 있다고 안내하고 있습니다.
쉽게 말해 정적 호스팅 중에는 ipx를 통해서 이미지 못 가져오니까
그냥 사전에 렌더링해서 사용하라는 말 같습니다.
우선 경로의 '/_ipx/'는 모두 동일하고 그 뒤에 w_120과 같은 경로는
NuxtImg 에서 제공하는 옵션을 사용하면 후술되는 경로들인데
이것은 본인이 사용한 옵션에 맞게끔 그리고 본인의 폴더 트리에 맞게끔 작성해주시면 됩니다.
참고로 저는 NuxtImg를 사용함에도 따로 옵션을 주지 않았습니다.(그럼 왜 씀..?)
아무튼 저의 경우에는
로 설정을 한 후 npm run generate 해보았을때
위와 같이 빌드 결과물에 _ipx로 시작하는 이미지 폴더와 함께 이미지 파일이 생성이 되었고
배포시에도 정상적으로 경로를 찾아 이미지를 보여줄 수 있는 것을 확인할 수 있었습니다!!
이 방법에도 문제가 있었는데
와일드카드 적용이 안된다는 것 입니다.
제가 와일드 카드를 이상하게 적었을 수도 있지만
우선 특정 경로 밑의 이미지 파일들에 대한 와일드카드 적용이 되지 않는 것 같았습니다...ㅠㅠ
이렇게 되면 수 많은 이미지 파일들의 경로를 하나하나 적어줘야 하는데
개발자가 되어서 이런 미련한 짓 할 수 없어서(귀찮아서) 결국 이 방법은 포기했습니다.
혹시라도 누군가 이 글을 보게 된다면
와일드카드 테스트 꼭 해주세요(나한테 방법 좀 알려줘..
아무튼 될거라고 생각했던 여러 방법 중 희망이었던 이 방법이 수포로 돌아가서 절망하고 있을 때
마지막으로 공문을 정독하던 중, 결국 방법을 찾았습니다.
- Custom Provider
https://image.nuxt.com/advanced/custom-provider
공문에서는 NuxtImg에 대한 경로를 커스텀해서 지정할 수 있도록 되어있었습니다.
즉, 사용자 지정 경로를 리턴할 수 있도록 커스텀 공급자를 설정할 수 있었습니다
방법은 아래와 같습니다.
import { joinURL } from 'ufo';
import type { ProviderGetImage } from '@nuxt/image';
import { createOperationsGenerator } from '#image';
const operationsGenerator = createOperationsGenerator();
export const getImage: ProviderGetImage = (src, { modifiers = {}, baseURL } = {}) => {
if (!baseURL) {
// also support runtime config
baseURL = useRuntimeConfig().public.siteUrl;
}
const operations = operationsGenerator(modifiers);
return {
url: joinURL(baseURL, src + (operations ? '?' + operations : ''))
};
};
image: {
providers: {
myProvider: {
name: 'myProvider',
provider: '@/providers/my-provider.ts'
}
}
},
<NuxtImg class="img" src="/img/폴더명/파일명.jpg" provider="myProvider" />
<주의>
Nuxt 에서는 이미지를 public 폴더에서 관리하기를 권장합니다.
사실 권장이라기보다 반강제입니다
관련한 컴포넌트 사용하려고 하다 보면 모두 다 public이 기본 경로더라구요..NuxtImg도 마찬가지고요..
실제로 NuxtImg 사용을 하지 않더라도 이미지의 기본 경로는 public 입니다..
위에 제시된 방법을 올바르게 사용하시려면 반드시 이미지들은
public 폴더 에서 관리해주세요!!!
또한 my-provider의 내용물은 baseUrl 등 자신의 개발 환경 및 배포 환경에 맞춰서 작성하셔야 합니다!
저 같은 경우
return {
url: joinURL('/내 레파지토리 url', src)
};
로 고정해두었습니다. 어짜피 앞으로 오랫동안 주소가 변하지도 않을거구요!
전 사실 이미지 최적화도 하지 않을거였지만... 뭔가 이걸 해결하고 싶었습니다 ㅋㅋㅋ 어찌보면 오기였던 것 같네요..
혹시라도 틀린 내용이 있거나 보충할 내용이 있다면 언제든 댓글로 말씀주시면 감사하겠습니다!!