Cloudflare + MongoDB: 'Error: Dynamic require of 'punycode/' is not supported' 오류 해결 방법
Source: Dev.to
TL;DR
@cloudflare/vite-plugin은 tr46 라이브러리 내부에서 뒤에 슬래시가 붙은 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 로 해결할 수 있습니다:
-
patch-package설치npm install patch-package --save-dev -
postinstall스크립트 추가 (매 설치 후 패치를 적용하고 기본cf-typegen스크립트도 실행):npm pkg set scripts.postinstall="patch-package && npm run cf-typegen" -
문제가 되는 파일 편집하여 뒤쪽 슬래시 제거:
sed -i '' 's/require("punycode\/")/require("punycode")/g' node_modules/tr46/index.js -
패치 생성:
npx patch-package tr46이 명령은 리포지토리에
patches/tr46+5.1.1.patch파일을 생성합니다. -
패치를 커밋 (코드베이스와 함께 전달되도록).
이제 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
요약
이와 같은 문제를 우회하기 위해 일시적인 의존성을 패치하는 것은 이상적이지 않지만, 이 특정 오류에 직면한 사람들에게는 해결책을 제공합니다. 요약하면:
-
patch-package설치npm install patch-package -
package.json업데이트 – 기존postinstall스크립트 앞에patch-package명령을 추가합니다:{ "scripts": { "postinstall": "patch-package && " } } -
소스 수정 –
node_modules/tr46/index.js파일을 편집하여require("punycode/")에서 끝나는/를 제거합니다. -
패치 생성
npx patch-package tr46 -
패치가 적용되었는지 확인
npm install
업스트림 이슈가 깔끔히 해결되기를 바랍니다 (보고된 이슈: cloudflare/workers-sdk#11751), 그 사이에 이 방법으로 프로젝트를 계속 실행할 수 있습니다.