renderToStaticNodeStream์€ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” React ํŠธ๋ฆฌ๋ฅผ Node.js Readable Stream์œผ๋กœ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

const stream = renderToStaticNodeStream(reactNode)

์ฐธ์กฐ

renderToStaticNodeStream(reactNode)

์„œ๋ฒ„์—์„œ renderToStaticNodeStream์„ ํ˜ธ์ถœํ•˜์—ฌ Node.js Readable Stream์„ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.

import { renderToStaticNodeStream } from 'react-dom/server';

const stream = renderToStaticNodeStream(<Page />);
stream.pipe(response);

์•„๋ž˜์—์„œ ๋” ๋งŽ์€ ์˜ˆ์‹œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

stream์€ React ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” HTML ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜

  • reactNode: HTML๋กœ ๋ Œ๋”๋งํ•  React ๋…ธ๋“œ. ์˜ˆ๋ฅผ ๋“ค์–ด <Page /> ์™€ ๊ฐ™์€ JSX ์—˜๋ฆฌ๋จผํŠธ.

๋ฐ˜ํ™˜๊ฐ’

HTML ๋ฌธ์ž์—ด์„ ์ถœ๋ ฅํ•˜๋Š” Node.js Readable Stream์ž…๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ HTML์€ ํด๋ผ์ด์–ธํŠธ์—์„œ hydrate ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ฃผ์˜ ์‚ฌํ•ญ

  • renderToStaticNodeStream์˜ ์ถœ๋ ฅ๊ฐ’์€ hydrate ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

  • ์ด ๋ฉ”์„œ๋“œ๋Š” ์ถœ๋ ฅ๊ฐ’์ด ๋ฐ˜ํ™˜๋˜๊ธฐ ์ „์— ๋ชจ๋“  Suspense boundaries๊ฐ€ ์™„๋ฃŒ๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

  • React 18๋ถ€ํ„ฐ ์ด ๋ฉ”์„œ๋“œ๋Š” ๋ชจ๋“  ์ถœ๋ ฅ๊ฐ’์„ ๋ฒ„ํผ๋งํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ŠคํŠธ๋ฆฌ๋ฐ์˜ ์ด์ ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • ๋ฐ˜ํ™˜๋œ ์ŠคํŠธ๋ฆผ์€ UTF-8๋กœ ์ธ์ฝ”๋”ฉ๋œ ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ์ธ์ฝ”๋”ฉ๋œ ์ŠคํŠธ๋ฆผ์ด ํ•„์š”ํ•˜๋‹ค๋ฉด, ํŠธ๋žœ์Šค์ฝ”๋”ฉ์„ ์œ„ํ•œ ๋ณ€ํ™˜ ์ŠคํŠธ๋ฆผ์„ ์ œ๊ณตํ•˜๋Š” iconv-lite์™€ ๊ฐ™์€ ํ”„๋กœ์ ํŠธ๋ฅผ ์‚ดํŽด๋ณด์„ธ์š”.


์‚ฌ์šฉ๋ฒ•

React ํŠธ๋ฆฌ๋ฅผ ์ •์  HTML๋กœ Node.js Readable Stream์— ๋ Œ๋”๋ง ํ•˜๊ธฐ

renderToStaticNodeStream์„ ํ˜ธ์ถœํ•˜์—ฌ ์„œ๋ฒ„ ์‘๋‹ต์œผ๋กœ ํŒŒ์ดํ”„ ํ†ต์‹  ํ•  ์ˆ˜ ์žˆ๋Š” Node.js Readable Stream์„ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.

import { renderToStaticNodeStream } from 'react-dom/server';

// ๋ผ์šฐํŠธ ํ•ธ๋“ค๋Ÿฌ ๋ฌธ๋ฒ•์€ ๋ฐฑ์—”๋“œ ํ”„๋ ˆ์ž„์›Œํฌ์— ๋”ฐ๋ผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.
app.use('/', (request, response) => {
const stream = renderToStaticNodeStream(<Page />);
stream.pipe(response);
});

stream์€ React ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” ์ดˆ๊ธฐ HTML ์ถœ๋ ฅ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์˜ํ•˜์„ธ์š”!

์ด ๋ฉ”์„œ๋“œ๋Š” hydrate ๋  ์ˆ˜ ์—†๊ณ  ์ƒํ˜ธ์ž‘์šฉํ•˜์ง€ ์•Š๋Š” HTML ์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” React๋ฅผ ๊ฐ„๋‹จํ•œ ์ •์  ํŽ˜์ด์ง€ ์ƒ์„ฑ๊ธฐ๋กœ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ด๋ฉ”์ผ๊ณผ ๊ฐ™์€ ์™„์ „ํžˆ ์ •์ ์ธ ์ฝ˜ํ…์ธ ๋ฅผ ๋ Œ๋”๋งํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ƒํ˜ธ์ž‘์šฉ์„ ์œ„ํ•œ ์•ฑ์€ ์„œ๋ฒ„์—์„œ renderToPipeableStream์„, ํด๋ผ์ด์–ธํŠธ์—์„œ hydrateRoot๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.