asyncfix

Proxy環境下でNode.jsのFetchがfailedするのを回避する方法

Astro Google Fonts OptimizerはNext.jsのFont Optimizationをインスパイアしたものですが、これはGoogleフォントをビルド時に取り込んでセルフホスティング化するものです。

Proxy環境下でfetch failedが発生

これらを導入したサイトをProxy環境下でnpm run devnpm run buildをすると、fetchがProxyを経由することができずに下記のようなエラーが発生します。

[ERROR] fetch failed
  Stack trace:
    at node:internal/deps/undici/undici:12344:11
    at runNextTicks (node:internal/process/task_queues:64:3)
    at process.callbackTrampoline (node:internal/async_hooks:130:17)
    at async Promise.all (index 0)
    [...] See full stack trace in the browser, or rerun with --verbose.

エラーに出力されていますが、Node.jsのfetchはundiciが使われており、それが原因となっています。Proxyが原因だと気づいたのは、同一コードを用いているにも関わらずProxy環境下の場合にだけエラーが発生したからです。
開発している環境がWindowsだったとして、環境変数にhttp_proxyhttps_proxyを設定していてもundiciは使ってくれないということですね。

Jamstack構成でSSGするとfetch failedが発生

以前、ヘッドレスCMSのAPIをNext.jsのfetchを使って取得し、SSGしようとした際もProxy環境下ではエラーが表示されたので、その際はaxiosとhttps-proxy-agentを使って回避したことがあります。Proxy環境下用に別途コードを実装するというのが、とても微妙だなという感想をその時は持ちました。
そういう経験があったので、今回、また同じfetch failedに遭遇した際にはすぐに原因はProxyだろうと推測が付きました。

undiciで環境変数のProxyを使う方法

冒頭のAstro Google Fonts Optimizerでのundiciエラーについては、undiciのリポジトリにissueが立っています。また、これに関連してNode.jsにもissueがあったり、global-agentでもissueがあります。

暫定的な解決方法としては、undiciのissueのこのコメントにあるよう、npm i undiciをした上でこのTypeScriptファイルを該当する.astroファイルにimportしてあげれば、開発機のWindowsに設定している環境変数http_proxyを自動で使ってくれるようになります。

これもProxy環境下用に別途コードを用意するという暫定的な対応なので個人的には微妙なのですが、簡易な方法で対応できるので現時点ではこれが一番良いのかなと思っています。