Spotify api에서 이미지 데이터를 불러오는 도중에 만난 소소한(?) 트러블슈팅…💣💥
이미지 불러오는 경로를 수정하거나 api 부분이 문제가 있던 적은 있었는데 next.config를 수정했던 적은 없어서 추후에 비슷한 문제가 발생했을 때 참고하려고 트러블슈팅 기록을 정리했다!
Next.js 사용시 외부 이미지 호스트 허용하기
Next.js 를 사용하면서 새로운 에러들을 많이 만나는 것 같다..ㅎㅎ
검색페이지를 만들면서 생긴 문제였는데 vscode 상에서 eslint
에러도 없었고 작성한 로직도 평소에 쓰던 방식과 유사해서 당연히 데이터가 브라우저에 나타나있을 줄 알았는데 아래 사진 같은 문구가 나타났다.
에러 문구 화면
대충 앞부분만 해석했을 때는 이미지의 src
주소가 prop
으로 잘못 내려졌다는게 무슨말인가 싶었다.
빨간 에러창을 무서워하지말자! ( •̀ᴗ•́ )و ̑̑ 차근차근 콘솔 에러를 다시 읽어보았다.
next image
태그의 hosename
이 next.config.js
에 설정이 되어있지 않다고 머라머라 하는 것 같았다.
next docs 주소까지 친절히 알려주길래 일단 냅다 들어가보았다.
이 코드처럼 next.config.js
파일에 가서 hostname
을 수정해주면 된다는 뜻이다.
나는 스포티파이에서 이미지를 불러오는 중인데 이 때 이미지 주소가 “https://i.scdn.co/image/~~~~”
로 시작하는 걸 확인할 수 있었다. 여기서 i.scdn.co
로 불러오는 이미지 주소를 설정이 되어있지 않았기 때문에 읽어올 수 없다고 오류메시지를 보낸 것이다.
// next.config.mjs
export default {
images: {
domains: ['i.scdn.co'], // Spotify의 이미지 호스트 도메인 추가
},
};
내 프로젝트에서는 next.config.mjs
파일로 세팅되어있는데 mjs
확장자는 ESM(ECMAScript Module)
형식을 사용하는 파일이어서 이에 맞는 방식으로 작성해줘야한다… Next.js는 ESM
방식, js
방식 모두 지원하기 때문에 파일 확장자를 수정할 필요 없이 ESM
방식에 맞는 방식으로만 추가해주면 된다.
파일을 수정해주고 yarn dev
로 서버를 다시 시작해주고 다시 확인해보면!
이렇게 오류 메시지도 없이 이미지를 잘 불러올 수 있게 되었다. 👏🏻👏🏻
오늘 발생한 오류는 Next.js의 next/image
컴포넌트가 외부 이미지 호스트에서 이미지를 불러올 때 발생한 문제였다. Next.js는 보안과 성능을 위해 기본적으로 외부 이미지 호스트를 허용하지 않는다고 한다!
때문에 외부 도메인에서 이미지를 불러오게 될 경우 해당 도메인을 next.config.js
(혹은 mjs 확장자 파일)에서 명시적으로 허용해주면 해결할 수 있다.
ESM 방식이 어떤건지 정리를 안 하면 약간 찝찝한 TIL 같아서..ㅎㅎ 따로 정리를 할까 하다가 트러블 슈팅이랑 같이 정리하는게 좋을 것 같아서 아래 추가하였다.
카카오테크 글을 보게 되었는데 전부 다 정리하기에는 내용이 많기도 하고 조금 어려워서 간단하게 정리해보려고 한다.
CommonJS
와 ESM
은 모듈 시스템을 별도 모듈로 내보내고 가져오는 문법이 다르다. 두 방식은 호환되지 않는다는 점이 주의사항이다!! (→ 나중에 팀프로젝트를 하면서 컨벤션 같은 거 정할 때 한 번 확인해야할 것 같다.)
01. 파일 확장자
.js
는 CommonJS.mjs
는 ESM02. 가장 가까운 상위 package.json의 “type” 필드 확인
module
인 경우 ESMcommonJS
또는 없는 경우 CommonJS03. Node.js --input-type 플래그 확인
-input-type=commonjs
인 경우 CommonJS-input-type=module
인 경우 ESMCommonJS : module.exports
사용
module.exports = {
someNumber: 123,
someMethod: () => {}
}
ESM
export default
: 특정 모듈 값 하나를 기본 내보내기export default {
something: 123
}
export
: 지정한 이름으로 값 내보내기export const namedVar = 'module';
export from
: 모듈을 불러와서 바로 내보내기export otherModule from './otherModule.js';
CommonJS :
require()
함수 사용 (ESM 파일 가져올 수 없음)
const module = require('./moduleFile');
ESM :
import 문
사용 (구문분석 단계에 모듈을 불러오기 때문에 동적인 값을 사용할 수 없음) CommonJS와 ESM 모듈을 둘 다 불러올 수 있으며 반드시 파일 확장자를 지정import { functionName } from './moduleFile.js';
// 모든 named export를 가져옵니다.
import * as allProperty from './moduleObject.js';
// 사용 불가
import {AorB_Module} from condition ? './A_module.js' : './B_module.js';
import()
표현식: 동적으로 모듈을 불러오기 위해서는 import 표현식 사용const module = await import('./moduleFile.js');
const aOrb_Module = await import(condition ? './A_module.js' : './B_module.js');
참고링크 :