ESM アジャイル事業部 開発者ブログ

永和システムマネジメント アジャイル事業部の開発者ブログです。

Next.jsでCSRからSSGにした時に生じたfetch(AbortSignal関連)のエラーについて

はじめに

日本のハワイのうちの1つ宮崎からお送りします*1。yoshinoです。

Next.jsのCSRの箇所をSSGに置き換えた時に、ローカルではエラーが起きないのに、Amplifyでデプロイした時に↓のようなエラーが生じました。また、node-fetch関連のエラーで起きていることもbacktraceには出力されていました。

ERROR: ApolloError: Expected signal to be an instanceof AbortSignal at new ApolloError

そのため、fetch + AbortControllerまわりで出ているエラーだということが考えられます。

ちなみに、AbortSignalはAbortController経由で非同期処理を中断するために利用され、fetchと組み合わせて利用されることも多いようです(詳しくはこちらを参照)。

今回は、SSGに変更したときに生じたことから、「Node.jsのバージョンがローカル(Docker image)とAmplifyで異なる 」 → 「fetch(AbortSignal)の実装が異なる」 → 「amplifyだけでエラー となる」ことが推察できました。

予想どおり、利用しているfetchのバージョンをどちらの環境で同じものを使うように変更をすることで、このエラーは解決できました(REF)。

import fetch from 'node-fetch';
import { abortableFetch } from 'abortcontroller-polyfill/dist/cjs-ponyfill';

global.fetch = abortableFetch(fetch).fetch

この記事ではNode.jsのバージョンによって、実装が異なる理由を少しだけ歴史をさかのぼって、確認してみることにします。

fetchとAbortControllerの浅い歴史

ブラウザ

今回の例はサーバーサイド(Node.js)環境の問題なので、ブラウザでは関係ありませんが、Node.jsとの比較のために確認してみます。Node.jsとブラウザのfetchやAbortControllerは対応関係はあると考えて良いと思いますが、同一のものではないことに注意してください。

fetch(Chrome: 2015-04~)

Chromeではバージョン42 (Released 2015-04-14)からサポートされています(REF)。

AbortController(Chrome: 2018-04~)

最新のすべての主要ブラウザーでAbortControllerhはサポートされています(REF)。Chromeはバージョン66 (Released 2018-04-17)からサポートされているようです。

ブラウザではfetch → AbortControllerの順序で対応されていることがわかります。

Node.js

AbortController(v15: 2021-04~)

Node.jsではv15からサポートされています(REF)。サポートされるまでの期間は、解決策の中であげているpolifyllを利用することが一般的なようです。

fetch(v18: 2023-04~)

fetchはv18からExperimentalでサポートされています。そして、このfetchではAbortControllerを利用することができます(REF)。サポートされるまでの期間はpolifyll(node-fetch)を利用して対応することが一般的です。

ブラウザとは異なり、Node.jsではAbortController → fetchの順序でサポートされています。

おわりに

以上のことから、今回のケースでは、ローカルでは最新のNode.jsのバージョンを利用しているので、AmplifyのNode.jsバージョンを最新に上げることでも、問題のエラーは解決できると思われます(まだ、試せていないのですが、ローカル環境とPROD環境のNode.jsバージョンを合わせて解決できるのであれば、それが一番良さそう)。

Node.jsのfetchの仕様は今後もバージョンにより大きく変わっていくことが予想される(v18時点では、ステータスはExperimentalですし、ブラウザのfetchの機能をすべてサポートしている訳ではない)ので、実行環境のNode.jsのバージョンとそのバージョンで何をサポートしているのかに注目すると、対応策が見えやすくなるのではないかと思います。

*1:日本にはハワイと呼ばれる箇所が複数あるようです。宮崎の海もとても綺麗なのでぜひ遊びに来てください。