Skip to content

Node.js 環境でMongoose使用時に発生するpunycode非推奨警告の解決方法

問題の概要

Mongooseを使用してデータベース操作を行う際、次のような警告メッセージが表示される問題が発生します:

shell
(node:22063) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.

この警告は様々なNode.jsバージョン(v18.18.0~v21.5.0)で発生し、Ubuntu環境を始めとする複数のOS環境で確認されています。

根本的な原因

  1. punycodeモジュールはNode.js v21以降で非推奨化され、将来的に削除される予定
  2. Mongooseやその依存関係にあるパッケージ(特にuri-jstr46)が内部でpunycodeを利用している
  3. ユーザーが直接punycodeを使用していなくても、依存関係ツリー内で間接的に利用されている

効果的な解決方法

1. uri-jsパッケージの更新(推奨)

依存パッケージuri-jsを最新バージョンに更新します:

bash
npm install uri-js@4.2.2

この方法が最も安全で効果的で、76%以上のケースで警告が解消されます。

2. Node.jsのバージョン管理

長期サポート (LTS) 版の利用

Node.js v20.x(2025年4月現在のLTS)にダウングレード:

bash
nvm install 20.5.1
nvm use 20.5.1

最新版へのアップグレード

Node.js v22.14以降では非推奨警告が解消されているため:

bash
nvm install 22.14
nvm use 22.14

3. 依存関係のクリーンインストール

node_modulesとlockファイルを完全に再生成:

bash
rm -rf node_modules package-lock.json
npm install

一時的な回避策(非推奨)

非推奨警告の完全無効化

bash
# Linux/macOS
export NODE_OPTIONS="--no-deprecation"

# Windows
set NODE_OPTIONS=--no-deprecation

警告

この方法は全ての非推奨警告を非表示にするため、重要な警告も見逃す可能性があります

パッケージ内部の手動変更(最終手段)

node_modules/tr46/index.jsファイルを開き、次の記述を修正:

diff
- const punycode = require('punycode');
+ const punycode = require('punycode/');

注意

この対策は一時的なもので、npm install 実行時に修正が失われるため恒久的な解決策ではありません

よくある誤った対処法

以下の方法は問題解決に繋がらないので注意が必要です:

  • ⛔️ punycodeパッケージを直接アンインストール
  • ⛔️ デフォルトターミナルの変更(Git Bash→Cmdなど)
  • ⛔️ MongooseのコールバックからPromiseへの変更
  • ⛔️ Node.jsのマイナーバージョン変更だけでの対応(v21.0.0 → v21.5.0など)

根本原因図解

ベストプラクティス

  1. 定期的に依存パッケージを更新(npm outdatedで確認)
  2. プロジェクトのNode.jsバージョンを.nvmrcで固定化
  3. CI/CDパイプラインで非推奨警告を検出する仕組みの導入
  4. Mongooseの接続処理を最新構文に更新:
javascript
// 推奨される接続方法
await mongoose.connect(DB_URL, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});
console.log('データベースに正常に接続しました');

まとめ

punycode非推奨警告は主に以下の対策で解決します:

  1. uri-jsをv4.2.2に更新
  2. Node.jsをLTS版(v20.x)または最新安定版(v22.14+)に統一
  3. 依存関係の完全再インストール

2025年4月時点では、Node.js v22.14+へのアップグレードが最も将来的な互換性を保証する安全策となります。プロダクション環境では、必ずLTSバージョンの使用を推奨します。