[備忘録]Proxy環境下でNode.jsのFetchErrorを回避する方法

# はじめに

企業で開発する場合にはネットワークにつなぐためにはProxyを指定することがあります。
この環境下でNext.jsを実行すると外 部APIやダウンロードなどのfetchを行うと`FetchError`が出てしまい接続できません。
その対策に対しての記事となります。

どちらかという自身の備忘録です。

# 対策前

以下のコマンドで、Next.jsのプロジェクトを作成します。

```sh
npx create-next-app@latest
```

プロジェクトフォルダ配下で以下のコマンドを実行しNext.jsを起動させます。

```sh
 npm run dev
 ```

[http://localhost:3000](http://localhost:3000)にアクセスすると以下のようなログが出ます。

```sh
> my-app@0.1.0 dev
> next dev

  ▲ Next.js 14.2.5
  - Local:        http://localhost:3000

 ✓ Starting...
 ✓ Ready in 1495ms
 ○ Compiling / ...
request to https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap failed, reason: self-signed certificate in certificate chain

Retrying 1/3...
request to https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap failed, reason: self-signed certificate in certificate chain

Retrying 2/3...
request to https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap failed, reason: self-signed certificate in certificate chain

Retrying 3/3...
FetchError: request to https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap failed, reason: self-signed certificate in certificate chain
    at ClientRequest.<anonymous> (C:\Users\XXXXXXXXX\Desktop\work\my-app\node_modules\next\dist\compiled\node-fetch\index.js:1:66160)
    at ClientRequest.emit (node:events:519:28)
    at TLSSocket.socketErrorListener (node:_http_client:500:9)
    at TLSSocket.emit (node:events:519:28)
    at emitErrorNT (node:internal/streams/destroy:169:8)
    at emitErrorCloseNT (node:internal/streams/destroy:128:3)
    at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
  type: 'system',
  errno: 'SELF_SIGNED_CERT_IN_CHAIN',
  code: 'SELF_SIGNED_CERT_IN_CHAIN'
}
 ⨯ Failed to download `Inter` from Google Fonts. Using fallback font instead.

Failed to fetch `Inter` from Google Fonts.}
 ✓ Compiled / in 5.1s (532 modules)
```

エラーの内容はダウンロードが失敗した文言です。
`SELF_SIGNED_CERT_IN_CHAIN`どうやら署名チェックでエラーが出ているみたいです。

# 対策

Next.jsは`.env`ファイルに環境変数を書くことができるので、ファイルを作成し以下の行を追加します。

```test:.env
NODE_TLS_REJECT_UNAUTHORIZED=0
```

仕様は以下となります。

https://nodejs.org/api/cli.html#node_tls_reject_unauthorizedvalue

> **NODE_TLS_REJECT_UNAUTHORIZED=value**
If value equals '0', certificate validation is disabled for TLS connections. 
This makes TLS, and HTTPS by extension, insecure. 
The use of this environment variable is strongly discouraged.

> **NODE_TLS_REJECT_UNAUTHORIZED=value**
値が '0' の場合、TLS 接続の証明書検証は無効になります。
これにより、TLS および拡張 HTTPS が安全ではなくなります。
この環境変数の使用は強く推奨されません。

:::note alert
仕様にもあるように、**TLS および拡張 HTTPS が安全ではなくなります。**
本設定はローカルの開発環境のみにしておいたほうが良いです。
:::

# 対策後

プロジェクトフォルダ配下で以下のコマンドを実行しNext.jsを起動させます。

```sh
 npm run dev
 ```

[http://localhost:3000](http://localhost:3000)にアクセスすると以下のようなログが出ます。

```sh
> my-app@0.1.0 dev
> next dev

  ▲ Next.js 14.2.5
  - Local:        http://localhost:3000
  - Environments: .env

 ✓ Starting...
(node:9436) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
(Use `node --trace-warnings ...` to show where the warning was created)
 ✓ Ready in 1816ms
 ○ Compiling / ...
 ✓ Compiled / in 2.2s (523 modules)
 GET / 200 in 2587ms
 ```

以下の警告がでますがダウンロードのエラーはでなくなります。

> (node:9436) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification.
(Use `node --trace-warnings ...` to show where the warning was created)

> (node:9436) 警告: NODE_TLS_REJECT_UNAUTHORIZED 環境変数を '0' に設定すると、証明書の検証が無効になり、TLS 接続と HTTPS リクエストが安全でなくなります。
(警告が作成された場所を表示するには、`node --trace-warnings ...` を使用します)

 # まとめ

 Proxy環境下でNext.jsの開発がしやすくなったと思います。
ただ、ローカル環境での開発のみの適用にする必要があります。