Node.js で fetch is not defined エラー:原因と対処法まとめ

スポンサーリンク

Node.js で fetch is not defined エラー:原因と対処法まとめ

Node.js で fetch is not defined が出るのは、使っている Node.js のバージョンが fetch をサポートしていないか、まだ実験的サポートの段階だからです。

ReferenceError: fetch is not defined

fetch が使えるようになったバージョン

Node.js バージョン fetch の状態
v17 以下 未対応(fetch 自体がない)
v18 〜 v20 実験的サポート(デフォルトで使える)
v21 以降 安定版(グローバルで使える)

fetch は Node.js v18 でグローバルに追加されました。v17 以下では標準では使えません。


現在の Node.js バージョンを確認する

node -v

v17 以下が表示された場合はバージョンアップが必要です。


バックエンドで fetch が使えないケース

バージョンが v18 以上でもエラーになるケースがあります。

Jest テスト環境

Jest のデフォルトテスト環境(jsdom)には fetch が含まれていません。

# jest.config.js のデフォルト
testEnvironment: "jsdom"  ← fetch がない

node 環境に切り替えるか、whatwg-fetch などのポリフィルが必要です。

// jest.config.js
module.exports = {
  testEnvironment: "node",  // node 環境では v18 以上なら fetch が使える
}

プロキシ環境(社内ネットワークなど)

Node.js の組み込み fetchHTTP_PROXY / HTTPS_PROXY 環境変数を自動参照しません。プロキシ経由が必要な環境では接続に失敗します。

# curl や axios は参照するが、Node.js fetch は参照しない
export HTTPS_PROXY=http://proxy.example.com:8080
node script.js  # fetch は依然プロキシを使わない

undiciProxyAgent を使うか、axios などプロキシ設定に対応したライブラリで対処します。

AWS Lambda の旧ランタイム

Node.js 14.x ランタイム(現在は EOL)には fetch がありません。ランタイムを Node.js 18.x 以上にアップグレードするのが最もシンプルな対処です。


対処法 1:Node.js を v18 以上にアップグレードする

最もシンプルな解決策です。mise を使っている場合はプロジェクトのバージョンを固定します。

# プロジェクトに Node.js v22 を設定する
mise use node@22

# グローバルに変更する
mise use --global node@22

# バージョン確認
node -v

対処法 2:node-fetch パッケージを使う

Node.js のバージョンを上げられない場合は node-fetch で fetch と同じ API を使えます。

npm install node-fetch
// ESModules(import)
import fetch from "node-fetch"

const res = await fetch("https://api.example.com/data")
const data = await res.json()

node-fetch v3 以降は ESModules のみ対応です。CommonJS(require)で使う場合は v2 を指定します。

npm install node-fetch@2
// CommonJS(require)
const fetch = require("node-fetch")

対処法 3:undici を使う(Node.js 公式推奨)

undici は Node.js の内部 HTTP クライアントです。v18 以降の fetch の実装もこれがベースになっており、プロキシ対応なども含め機能が豊富です。

npm install undici
import { fetch, ProxyAgent } from "undici"

// 通常の fetch
const res = await fetch("https://api.example.com/data")
const data = await res.json()

// プロキシ経由
const dispatcher = new ProxyAgent("http://proxy.example.com:8080")
const res = await fetch("https://api.example.com/data", { dispatcher })

対処法 4:axios を使う(サードパーティライブラリ全般の注意あり)

注意: axios をはじめとするサードパーティの HTTP ライブラリは、過去に脆弱性が報告されたことがあります(例:axios CVE-2023-45857)。導入する場合は npm audit で定期的に確認し、常に最新バージョンを維持してください。

上記を踏まえた上で、axios はプロキシ設定への対応や CommonJS・ESM 両対応など、実用的な選択肢の一つです。

npm install axios
import axios from "axios"

const { data } = await axios.get("https://api.example.com/data")
console.log(data)

// プロキシ設定
const { data } = await axios.get("https://api.example.com/data", {
  proxy: {
    host: "proxy.example.com",
    port: 8080,
  },
})

TypeScript で型エラーになる場合

TypeScript で fetch の型が見つからないと言われる場合は @types/node を最新に更新します。

npm install --save-dev @types/node@latest

tsconfig.jsontarget / lib が古いと型定義が含まれないこともあります。

{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["ES2020"],
    "module": "NodeNext",
    "moduleResolution": "NodeNext"
  }
}

まとめ

状況 対処法
Node.js v17 以下 v18 以上にアップグレード(推奨)
バージョンを上げられない node-fetch@2(CommonJS)/ node-fetch(ESM)
プロキシ環境 undici(ProxyAgent)または axios
Jest テスト環境 testEnvironment: "node" に変更
AWS Lambda 旧ランタイム Node.js 18.x 以上のランタイムに変更
TypeScript の型エラーのみ @types/node を最新に更新
Node.js v21 以上・通常環境 何もしなくても fetch が使える

Node.js のバージョン管理には mise が便利です。「mise で Node.js をインストールする方法:.tool-versions でバージョン固定」も参照してください。

fetch が使えるようになったら、エラーハンドリングも合わせて確認しておきましょう。「Node.js fetchのエラーハンドリング入門:TypeScriptで型安全に書く