Skip to content
Published:

Astro で Warning ReactDOMServer.renderToStaticNodeStream() is deprecated. が出るようになった原因と対応

Astro で突然非推奨の警告が出るようになった

このサイトは Astro で実装されており、一部コンポーネントに React を使用しています。 ある日を境に、開発サーバの起動ログに以下のような警告が出るようになりました。

Warning: ReactDOMServer.renderToStaticNodeStream() is deprecated. Use ReactDOMServer.renderToPipeableStream() and wait to `pipe` until the `onAllReady` callback has been called instead.

メッセージで検索してみると、同様の Issue が GitHub に起票されており、対応の Pull Request もマージされていました。

Warning: ReactDOMServer.renderToStaticNodeStream() is deprecated. · Issue #10899 · withastro/astro
Astro Info Astro v4.7.0 Node v20.11.1 System macOS (arm64) Package Manager unknown Output static Adapter none Integrations @astrojs/tailwind @astrojs/react @astrojs/sitemap If this issue only occur...
Warning: ReactDOMServer.renderToStaticNodeStream() is deprecated.  · Issue #10899 · withastro/astro favicon github.com
Warning: ReactDOMServer.renderToStaticNodeStream() is deprecated.  · Issue #10899 · withastro/astro

fix a deprecated method in react integration using SSR: renderToStaticNodeStream by Angrigo · Pull Request #10893 · withastro/astro
Changes ReactDOMServer.renderToStaticNodeStream() is deprecated. Use ReactDOMServer.renderToPipeableStream() and wait to pipe until the onAllReady callback has been called instead. Testing Tested m...
fix a deprecated method in react integration using SSR: renderToStaticNodeStream by Angrigo · Pull Request #10893 · withastro/astro favicon github.com
fix a deprecated method in react integration using SSR: renderToStaticNodeStream by Angrigo · Pull Request #10893 · withastro/astro

2024/05/01 時点ではまだリリースされていませんが、数日以内にリリースされると思われるため、@astrojs/react のバージョンアップで修正されると考えられます。

2024/05/03 追記: 変更がリリースされ、警告が出なくなりました。 https://github.com/withastro/astro/blob/HEAD/packages/integrations/react/CHANGELOG.md#332

この記事ではそもそもなぜこの警告が出るようになったのかを調査しました。

前提

どの箇所を起因として警告が出るようになったのか

astro/packages/integrations/react/server.js at c238aa81ee91ce85f40740234fe6878faa27dceb · withastro/astro
The web framework for content-driven websites. ⭐️ Star to support our work! - withastro/astro
astro/packages/integrations/react/server.js at c238aa81ee91ce85f40740234fe6878faa27dceb · withastro/astro favicon github.com
astro/packages/integrations/react/server.js at c238aa81ee91ce85f40740234fe6878faa27dceb · withastro/astro

Astro の react インテグレーションで ReactDOM.renderToStaticNodeStream() が使用されている箇所がありました。

Deprecate `renderToStaticNodeStream` (#28872) by gnoff · Pull Request #28874 · facebook/react
This commit adds warnings indicating that renderToStaticNodeStream will be removed in an upcoming React release. This API has been legacy, is not widely used (renderToStaticMarkup is more common) a...
Deprecate `renderToStaticNodeStream` (#28872) by gnoff · Pull Request #28874 · facebook/react favicon github.com
Deprecate `renderToStaticNodeStream` (#28872) by gnoff · Pull Request #28874 · facebook/react
github.com
github.com favicon github.com

React 側では 2024/04/25 の 18.3.0 のリリースでこの警告を追加しています。

description を確認すると次の理由から非推奨に指定されたことがわかります。

This API has been legacy, is not widely used (renderToStaticMarkup is more common) and has semantically eqiuvalent implementations with renderToReadableStream and renderToPipeableStream.

ReactDOMServer.renderToStaticNodeStream() とは何か?

ReactDOMServer は、サーバ上で React コンポーネントをレンダリングするための API を指しており、具体的なパッケージは react-dom/server です。 いわゆる Static-Site Generation や Server-Side Rendering と言われるような事前レンダリングに用いられます。

サーバ用 React DOM API – React
The library for web and native user interfaces
サーバ用 React DOM API – React favicon ja.react.dev
サーバ用 React DOM API – React

この API 群には動作環境とレンダリング結果の分類によっていくつかのメソッドが用意されているようです。

環境メソッドストリームハイドレーション
Node.jsrenderToPipeableStream
Node.jsrenderToStaticNodeStream不可
Web StreamrenderToReadableStream
ストリームサポートなしrenderToString不可不可
ストリームサポートなしrenderToStaticMarkup不可不可

上記の表の繰り返しになりますが、renderToStaticNodeStream は Node.js 環境において、React コンポーネントをストリームとして出力するための API を指します。

React ではなぜ ReactDOMServer.renderToStaticNodeStream() が非推奨となったのか

ドキュメントを参照すると、注意点として以下の内容が記載されています。

renderToStaticNodeStream の出力はハイドレーションすることができません。 React 18 時点において、このメソッドはすべての出力をバッファリングするため、実際にはストリームを使用する利点が得られません。

この特徴を踏まえると、renderToStaticNodeStream は実際にはストリームとしての利点を享受できないため、ケースによって既存のメソッドに置き換えることができそうです。

ユースケースをカバーできる他の API があるので、renderToStaticNodeStream は非推奨となったと考えられます。

補足: Astro における対応

if ("renderToReadableStream" in ReactDOM) {
  html = await renderToReadableStreamAsync(vnode, renderOptions);
} else {
  html = await renderToPipeableStreamAsync(vnode, renderOptions);
}

Astro では、環境に応じて renderToReadableStreamrenderToPipeableStream を使うようになっていました。

参考

www.reddit.com
www.reddit.com favicon www.reddit.com