브랜드 가이드 프로젝트를 작업 중 로고 파일이 다운은 되는데 열리지 않는 문제가 발생했다.
같은 이름의 zip 파일로 다운은 되는데 지원되지 않는 포맷이라는 단어가 너무 당황스러웠다.
(2) 파일은 배포 된 후 다운받은 파일 (3)은 개발환경에서 다운 받은 파일이다.
용량 차이만 봐도 말이 안되게 크기가 다르다. 그래서 단순히 파일 형식의 문제가 아니고 이름만 같을뿐 원하는 파일이 다운이 되지 않고 있다는 것을 알게 되었다.
현재 에셋이 저장된 폴더 디렉토리 이렇게 구성되어 있다.
- public
- /*로고 이미지 파일*/
- src
- assets
- /*.svg, .png 파일들*/
개발 서버에서 public
에 있는 에셋에 접근하기 위해서는
const renderHeader = () => {
return <header>
<Heading1>Brand Guide</Heading1>
<a href={"../../public/Mobileindex_Logo_230905ver.zip"}
rel={"noreferrer"}
target={"_blank"} download>
<span id={'button'}>
<BodyB>로고 파일 다운로드</BodyB>
<DownloadIcon/>
</span>
</a>
</header>
}
href에 적힌 상대경로로 접근하고 있다.
하지만 build 후 저장된 public의 일은 deploy/dist
바로 아래에 저장되어 있었다.
여기서 vite의 공식 문서를 읽으면
https://ko.vitejs.dev/guide/assets.html#the-public-directory
public 디렉터리에 위치해 있는 에셋을 가져오고자 하는 경우, 항상 루트를 기준으로 하는 절대 경로로 가져와야만 합니다. ( public/icon.png 에셋은 소스 코드에서 /icon.png으로 접근이 가능합니다.)
라고 나와있다.
const renderHeader = () => {
return <header>
<Heading1>Brand Guide</Heading1>
<a href={"/Mobileindex_Logo_230905ver.zip"}
rel={"noreferrer"}
target={"_blank"} download>
<span id={'button'}>
<BodyB>로고 파일 다운로드</BodyB>
<DownloadIcon/>
</span>
</a>
</header>
}
변경 후 성공적으로 파일이 다운도 되며 무사히 압축도 해제되는걸 확인 할 수 있었다!.
문제를 해결하다보니 추가로 궁금한 점이 생겼다.
모듈로 assets을 import 할때는 똑같이 상대경로를 사용해도 잘 나오는데,
왜 <a href/> 에서는 파일을 제대로 접근을 못할까?
라는 의문점이 생겼다.
챗 GPT를 활용해서 그 답변을 얻을 수있었다.
개발서버에서는 정적 파일을 접근할때 실시간으로 파일을 서빙하므로 상대경로를 입력해도 파일에 접근하고 다운로드 하는데 아무런 문제가 없다.
하지만 빌드의 결과물이 배포한 후에 파일을 접근을 할려면 상대경로는 사용할 수 없다!!
빌드된 결과물은 일반적으로 서버에 호스팅되고 서버에서는 클라이언트의 요청에 대해 정적 파일을 제공하기 때문이다.
그래서 배포된 결과물을 사용하기 위해서는 절대경로를 사용해야 한다.!!(중요)
Vite는 모듈 시스템을 이용하는 경우 자동으로 상대경로를 절대경로로 변환한다.
그래서 import a from "../../../assets/a.png" 와 같은 상대 경로를 사용하는 코드는 Vite로 빌드시 자동으로 절대경로로 변환된다.
하지만!!! HTML 파일의 <a>
태그에서는 이러한 자동 변환이 일어나지 않는다. 🥹
이러한 이유로 에셋을 사용할때 상대경로르 입려했지만 로고이미지 다운에서만 문제가 발행하였다.
모듈로 import 되지 않는 에셋을 사용하가 위헤서는 절대 경로를 사용하는 것이 더 안전하다!