본문 바로가기
코딩이야기/트러블슈팅

[Next.js] sharp 라이브러리 적용 후 vercel 배포 시 런타임 오류 발생

by TaeHyeon0412 2024. 7. 13.

문제상황

https://taehyeon-smilestudy.tistory.com/51

 

[Next.js] AWS S3 업로드 이미지 최적화를 해보자! (feat. sharp)

이미지 최적화란?이미지 최적화는 웹사이트의 성능과 속도를 향상시키기 위해 품질을 손상시키지 않으면서 이미지의 파일 크기를 줄이는 프로세스입니다. 이 프로세스에는 크기를

taehyeon-smilestudy.tistory.com

 

sharp 라이브러리를 적용 후 vercel 배포를 했더니 런타임 오류가 발생했습니다.

 

Vercel에서 sharp와 관련하여 발생하는 오류는 sharp가 대상 환경에 맞게 특별히 컴파일되어야 하는 기본 모듈이라는 사실 때문입니다. Vercel은 Linux 환경을 사용하며 설치된 sharp 모듈이 linux-x64 런타임과 호환되지 않는다는 오류가 나타납니다.

 

이런 이유 때문이라고 합니다.

제가 사용하는 개발 환경은 window라서 Vercel은 Linux 환경과 맞지 않아서 런타임 오류가 뜬 것 같군요.

 

이 문제를 해결하기 위해 기존에 설치된 'sharp' 모듈을 제거합니다.

npm uninstall sharp

 

sharp 모듈을 플랫폼과 아키텍처를 지정하여 다시 설치합니다.

npm install sharp --platform=linux --arch=x64

 

선택적 종속성을 포함하여 설치합니다.

npm install --include=optional sharp

 

 

그리고 오류가 다시 날 경우를 대비하여 실패하면(환경에서 모듈을 사용할 수 없는 경우)
오류를 기록하고 대체하는 코드를 만들었습니다.

//items/upload/action.ts
//기존에 있던 import sharp 제거 

let sharp: typeof import("sharp") | undefined; 
try {
  sharp = require("sharp");
} catch (error) {
  console.error("로드 실패 sharp module:", error);
}


//sharp가 로드 안될 때 사용해야 되니 
//let 변수를 선언 후 sharp 이거나 undefined일 수 있음을 선언합니다.
//sharp 모듈이 성공적으로 로드되면 sharp 변수에 할당됩니다.
//만약 모듈 로드 중 오류가 발생하면 catch 블록이 실행되고, 오류 메시지를 콘솔에 출력합니다.

 

 

그 후 if문을 이용해 sharp가 정삭 동작할 때, 동작하지 않을 때를 만들어줍니다. 

export async function uploadItem(_: any, formData: FormData) {
  const data = {
    photo: formData.get("photo"),
    title: formData.get("title"),
    price: formData.get("price"),
    description: formData.get("description"),
  };

  if (data.photo instanceof File) {
    const photoData = await data.photo.arrayBuffer();

    let optimizedPhoto: Buffer;

    // Sharp를 사용하여 이미지 최적화 if문 사용
    if (sharp) {
      optimizedPhoto = await sharp(Buffer.from(photoData))
        .webp({ quality: 95 }) // WebP 형식으로 변환 및 압축 품질 설정
        .toBuffer();
    } else {
      optimizedPhoto = Buffer.from(photoData);
      //sharp가 정상 동작하지 않으면 그대로 넣는 대체 구문
    }

    const imgName = `${Date.now()}-${data.photo.name.split(".")[0]}.webp`;
    //Sharp를 사용하여 webp형식으로 바꿨으니 파일명도 webp 형식으로 바꿔줌

    const params = {
      Bucket: bucketName!, // bucketName이 undefined가 아님을 명시적으로 알림
      Key: imgName, // 고유한 파일 이름 생성
      Body: optimizedPhoto,
      ContentType: "image/webp",
    };

    try {
      const uploadResult = await s3.upload(params).promise();
      data.photo = uploadResult.Location;
    } catch (error) {
      console.error("실패지점:", error);
    }
  }

 

완성!  vercel 배포 후 테스트를 해주었습니다.

대체 코드로 빠짐..

 

vercel에서 sharp가 제대로 로드 되지 않고 런타임 오류와 함께 대체 코드로 빠져버립니다 ㅠㅠ

오류가 날 구멍은 없는데 왜 그런건가 구글 폭풍 서치.....
2시간이 넘게 시행착오를 하다 sharp 공식 github issues탭에서 답을 찾았습니다.

https://github.com/lovell/sharp/issues/3870

 

Vercel only: 0.33.0: error Could not load the "sharp" module using the linux-x64 runtime · Issue #3870 · lovell/sharp

Possible bug Is this a possible bug in a feature of sharp, unrelated to installation? Running npm install sharp completes without error. Running node -e "require('sharp')" completes without error. ...

github.com

 

허탈하게도 0.33.0 버전에 문제가 있었나 봅니다.......

기존 버전을 제거 후
0.32.6 버전으로 다운그레이드를 해주었습니다.

npm uninstall sharp
npm install sharp@0.32.6 --platform=linux --arch=x64


배포 후 테스트


444.4KB -> 122.7KB로 약 72%가 감소한 것을 볼 수 있습니다.

하...!!!!


열이 받지만 아무튼 잘 해결 되었습니다.
다음부터 안될떄는 버전 이슈가 있는지 먼저 확인 해봐야겠습니다.

 

 

해결완료