Cloudflare + MongoDB: 'Error: Dynamic require of 'punycode/' is not supported' 오류 해결 방법

발행: (2025년 12월 31일 오후 10:50 GMT+9)
6 min read
원문: Dev.to

Source: Dev.to

TL;DR

@cloudflare/vite-plugintr46 라이브러리 내부에서 뒤에 슬래시가 붙은 import를 처리합니다 (MongoDB Node.js 드라이버의 전이 의존성). 현재 해결책은 적절한 수정이 적용될 때까지 이 import를 패치하는 것입니다.

재현

문제를 재현하는 최소 프로젝트를 생성합니다.

# 1️⃣ 새로운 React‑Router 앱 만들기
npm create cloudflare@latest -- my-react-router-app --framework=react-router
cd my-react-router-app

# 2️⃣ MongoDB 드라이버 설치
npm install mongodb --save

# 3️⃣ Workers 진입점에 import 앞에 추가
printf 'import { MongoClient } from "mongodb";\n%s' "$(cat workers/app.ts)" > workers/app.ts

# 4️⃣ Node.js 호환 플래그 활성화 (SSR에 필요)
sed -i '' '/"compatibility_date": "2025-04-04"/a\
  "compatibility_flags": ["nodejs_compat"],' wrangler.jsonc

앱 실행

npm run dev

다음과 같은 출력이 나타납니다:

11:15:07 AM [vite] (ssr) Re-optimizing dependencies because vite config has changed
11:15:08 AM [vite] (ssr) ✨ new dependencies optimized: mongodb
11:15:08 AM [vite] (ssr) ✨ optimized dependencies changed. reloading
[vite] program reload
Error: Dynamic require of "punycode/" is not supported
    at null. (/.../node_modules/.vite/deps_ssr/chunk-PLDDJCW6.js:11:9)

Vite가 punycode/(끝에 슬래시가 있는) 동적 require를 지원하지 않는다고 불평하고 있습니다.

원인 찾기

npm ls punycode

출력:

my-react-router-app@ /.../my-react-router-app
└─┬ mongodb@7.0.0
  └─┬ mongodb-connection-string-url@7.0.0
    └─┬ whatwg-url@14.2.0
      └─┬ tr46@5.1.1
        └── punycode@2.3.1

tr46의 진입점(node_modules/tr46/index.js)을 확인합니다:

"use strict";

const punycode = require("punycode/"); // ← 문제의 라인
const regexes = require("./lib/regexes.js");
const mappingTable = require("./lib/mappingTable.json");
const { STATUS_MAPPING } = require("./lib/statusMapping.js");
// …

끝에 슬래시가 붙어 있기 때문에 Vite의 번들러가 이 import를 동적 require로 처리하게 되며, 이는 Workers 런타임에서 지원되지 않습니다.

tr46에 대한 PR이 열렸습니다 (#73(https://github.com/jsdom/tr46/pull/73)), 하지만 유지보수자는 문제가 라이브러리 자체가 아니라 Vite에서 비롯된다고 밝혔습니다. 슬래시를 도입한 커밋(fef6e95)은 내장 punycode 모듈에 대한 폐지 경고를 억제하기 위한 것이었습니다.

의존성 패치

문제를 patch‑package 로 해결할 수 있습니다:

  1. patch-package 설치

    npm install patch-package --save-dev
  2. postinstall 스크립트 추가 (매 설치 후 패치를 적용하고 기본 cf-typegen 스크립트도 실행):

    npm pkg set scripts.postinstall="patch-package && npm run cf-typegen"
  3. 문제가 되는 파일 편집하여 뒤쪽 슬래시 제거:

    sed -i '' 's/require("punycode\/")/require("punycode")/g' node_modules/tr46/index.js
  4. 패치 생성:

    npx patch-package tr46

    이 명령은 리포지토리에 patches/tr46+5.1.1.patch 파일을 생성합니다.

  5. 패치를 커밋 (코드베이스와 함께 전달되도록).

이제 npm install이 실행될 때마다 patch-package가 자동으로 수정 사항을 다시 적용합니다.

전체 패치 스크립트 (복사‑붙여넣기)

# 1️⃣ patch‑package 설치
npm install patch-package --save-dev

# 2️⃣ postinstall 스크립트 추가 (기존 cf-typegen 유지)
npm pkg set scripts.postinstall="patch-package && npm run cf-typegen"

# 3️⃣ 설치된 패키지의 import 수정
sed -i '' 's/require("punycode\/")/require("punycode")/g' node_modules/tr46/index.js

# 4️⃣ 패치 파일 생성
npx patch-package tr46

위 단계를 실행한 후, 개발 서버를 재시작합니다:

npm run dev

이제 “Dynamic require of “punycode/” is not supported” 오류가 나타나지 않으며, MongoDB 드라이버가 Cloudflare Worker에서 정상적으로 로드됩니다.

다음은?

  • 업스트림 tr46 저장소를 주시하세요 – 슬래시가 없는 버전을 릴리스하면 패치를 제거할 수 있습니다.
  • 다른 라이브러리에서 유사한 문제가 발생하면, 동일한 patch-package 방식을 임시 해결책으로 사용할 수 있습니다.

행복한 해킹!

위의 변경 사항

npx patch-package tr46
# reinstall and apply patches
npm install

요약

이와 같은 문제를 우회하기 위해 일시적인 의존성을 패치하는 것은 이상적이지 않지만, 이 특정 오류에 직면한 사람들에게는 해결책을 제공합니다. 요약하면:

  1. patch-package 설치

    npm install patch-package
  2. package.json 업데이트 – 기존 postinstall 스크립트 앞에 patch-package 명령을 추가합니다:

    {
      "scripts": {
        "postinstall": "patch-package && "
      }
    }
  3. 소스 수정node_modules/tr46/index.js 파일을 편집하여 require("punycode/")에서 끝나는 /를 제거합니다.

  4. 패치 생성

    npx patch-package tr46
  5. 패치가 적용되었는지 확인

    npm install

업스트림 이슈가 깔끔히 해결되기를 바랍니다 (보고된 이슈: cloudflare/workers-sdk#11751), 그 사이에 이 방법으로 프로젝트를 계속 실행할 수 있습니다.

Back to Blog

관련 글

더 보기 »

ASP.NET Core에서 Worldpay 웹훅 디버깅

소개 Worldpay를 프로덕션 ASP.NET Core 애플리케이션에 통합할 때, webhook 실패를 디버깅하는 것은 가장 어려운 문제 중 하나가 될 수 있습니다. 이벤트는 …