React Three Fiber를 사용한 프로젝트에서 .gltf 모델이 로컬 개발 환경에서는 정상적으로 로드되지만, 배포 환경(AWS EC2 + Nginx) 에서는 모델이 로드되지 않는 문제를 해결한 과정을 공유합니다.
문제 상황
Three.js 기반 GLTF 모델을 배포 서버에서 로드하려고 했을 때 다음과 같은 에러가 발생했습니다.
Could not load /assets/warehouse_props-BK1-B-1u.gltf: Invalid typed array length: 2112
Unexpected Application Error! Could not load /warehouse_props/warehouse_props.gltf: Unexpected token '<', "<!doctype "... is not valid JSON
개발 환경(localhost)에서는 문제가 없었고, 동일한 코드로 빌드 및 배포했음에도 EC2 환경에서는 GLTF 로딩에 실패했습니다.
원인 분석
여러 차례 디버깅을 거쳐 문제의 원인을 아래와 같이 정리할 수 있었습니다.
- 잘못된 파일 경로 요청
- .gltf 파일을 요청했지만 해당 경로에 파일이 존재하지 않아 Nginx가 index.html을 반환함
- 이로 인해 GLTFLoader는 HTML을 JSON으로 파싱하려 하다가 실패
- .gltf 내부 참조 깨짐
- .gltf 파일은 내부적으로 .bin 파일이나 .png 텍스처 파일을 상대 경로로 참조함
- 번들링 과정에서 이 경로가 깨지면 로딩에 실패하게 됨
- Vite 빌드 시 파일 이름 및 위치 변경
- Vite가 .gltf, .bin, .png 파일을 assets 폴더로 이동하면서 해시가 붙은 파일명으로 변경
- .gltf 내부에 정의된 상대 경로와 실제 배포된 경로가 불일치하여 오류 발생
해결 과정
1. public 폴더 활용
GLTF 파일을 src/assets 내부에서 import하지 않고, public/ 폴더에 다음과 같이 직접 배치했습니다.
public/
├── warehouse_props/
│ ├── warehouse_props.gltf
│ ├── warehouse_props.bin
│ └── *.png
import warehouse_props from '/warehouse_props/warehouse_props.gltf';
이는 브라우저에서 /warehouse_props/warehouse_props.gltf 로 직접 요청하게 되며, 번들링된 결과에 영향을 받지 않고 상대 경로도 그대로 유지됩니다.
2. Vite 설정
Vite에서 .gltf 관련 파일이 번들링 대상에 포함되지 않도록 설정을 명시했습니다.
assetsInclude: ['**/*.gltf', '**/*.glb', '**/*.bin', '**/*.png']
또한, build.rollupOptions.output.assetFileNames 옵션을 설정하여 .gltf, .bin, .png 파일의 이름이 해시되지 않도록 예외 처리했습니다.
assetFileNames: (assetInfo) => {
if (/\.(gltf|bin|png)$/.test(assetInfo.name!)) {
const folder = assetInfo.name?.includes('warehouse_props') ? 'warehouse_props' : 'warehouse';
return `${folder}/[name][extname]`;
}
return 'assets/[name]-[hash][extname]';
},
다만 위 설정은 public/ 폴더에서 정적 로딩을 사용하는 경우 필수는 아닙니다.
배포 환경 설정 확인
Nginx 설정에서 .gltf, .bin, .png 파일에 대한 MIME 타입 지정과 CORS 허용, 캐시 설정이 누락되지 않았는지 확인했습니다.
location ~* \.(gltf|glb)$ {
gzip off;
types { }
default_type model/gltf-binary;
add_header Cache-Control "public, max-age=31536000";
add_header Access-Control-Allow-Origin *;
}
이후에는 로컬과 배포 환경 모두에서 .gltf 모델이 정상적으로 로딩되었고, 텍스처가 깨지거나 JSON 파싱 오류가 나는 문제가 해결되었습니다.
이번 이슈는 파일 경로 구조, 빌드 방식, Nginx 설정, Three.js의 로딩 방식까지 전반적인 이해가 필요했던 문제였습니다.
React Three Fiber에서 GLTF 모델을 로드할 때는 다음을 고려해보는 것이 중요합니다.
- .gltf, .bin, .png는 동일 폴더에 유지한다.
- public/ 폴더를 활용하여 정적 경로로 직접 로드한다.
- GLTFLoader가 참조하는 상대 경로가 깨지지 않도록 관리한다.
'개발' 카테고리의 다른 글
| [사이드 프로젝트] 커맨드 패턴(Command Pattern)을 적용한 리팩토링 (0) | 2025.07.16 |
|---|