개발 slecs

SSR 빌드 안정화를 위해 mysql2를 번들에서 제외한 이유

목차

Vite 기반 SSR 프로젝트에서 mysql2를 번들에서 제외하도록 설정을 수정했다. 번들링 오류를 막기 위한 작업인데, SSR과 SEO의 맥락에서 꽤 중요한 변경이라 정리해본다.

SSR 빌드와 의존성 번들링의 함정

Astro처럼 SSR을 지원하는 프레임워크에서 Vite를 쓸 때 자주 마주치는 문제다. 서버 사이드에서 HTML을 렌더링할 때 필요한 라이브러리들이 번들에 포함되는데, 모든 라이브러리가 번들링에 친화적이지는 않다는 게 핵심이다.

특히 mysql2 같은 데이터베이스 드라이버는 네이티브 바인딩(C++ 확장)을 포함하고 있다. 이런 라이브러리를 Rollup 같은 번들러가 무작정 번들에 넣으려고 하면:

  • 번들 크기가 불필요하게 커짐
  • 런타임에 네이티브 모듈을 찾지 못해 오류 발생
  • 서버 환경과 빌드 환경의 아키텍처 차이로 인한 호환성 문제

결국 SSR 빌드가 실패하거나, 배포 후 런타임 에러로 이어진다.

해결책: Externalize 설정

// astro.config.mjs 예시
export default defineConfig({
  vite: {
    ssr: {
      external: ['mysql2'],
      // 혹은 정규식으로 여러 개
      // external: [/^mysql2/]
    },
    build: {
      rollupOptions: {
        external: ['mysql2']
      }
    }
  }
});

external 옵션은 "이 라이브러리는 번들에 넣지 말고, 런타임에 이미 설치되어 있다고 가정하라"는 의도다. Node.js 환경에서는 node_modules에서 직접 로드하도록 남겨두는 것.

SEO와의 연결고리

여기서 "seo" 라벨이 붙은 이유는, SSR이 제대로 작동해야만 SEO가 작동하기 때문이다.

  • SSR이 실패하면 서버에서 완전한 HTML을 보낼 수 없음
  • 검색 엔진 크롤러는 JavaScript 해석을 못하므로 서버의 HTML에 의존
  • SSR 빌드 오류나 런타임 에러는 곧 잘못된 HTML 응답 또는 500 에러로 이어짐

결국 이 fix는 "SSR 파이프라인을 안정화시켜서 검색 엔진이 올바른 콘텐츠를 수집하게 한다"는 의도를 담고 있다.

비슷한 사례들

이런 외부화 처리는 mysql2뿐 아니라:

  • sqlite3, pg(PostgreSQL 드라이버) — 네이티브 바인딩
  • bcrypt, argon2 — 암호화 라이브러리
  • sharp, canvas — 이미지 처리 네이티브 모듈
  • esbuild, piscina — 번들러 자체

등에서도 자주 필요하다. 번들링되지 말아야 할 라이브러리를 찾아내는 건 SSR 프로젝트의 기본 체크리스트 중 하나가 되어야 한다.

회고

이 fix를 하면서 배운 점은, 번들링 설정이 "자동으로 모든 걸 번들에 넣는 게 맞다"는 가정에서 출발하면 곤란하다는 것. SSR 환경에서는 서버에서 직접 실행되는 코드는 번들되지 않는 게 낫다는 원칙을 먼저 가져야 한다. 특히 네이티브 모듈이 포함된 라이브러리들은 무조건 외부화 리스트에 넣고 시작하는 게 나중에 런타임 문제를 줄인다.

앞으로 SSR 기반 프로젝트를 셋업할 때는 초기 단계부터 "네이티브 의존성은 어떤 걸 쓸 예정인가", "그걸 externalize 할 수 있나" 체크하는 게 좋겠다는 생각이 들었다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.