[우아한테크코스] SSR 직접 구현하면서 이해하기
✅ 코드 흐름으로 SSR 이해
코드를 한줄씩 따라가며 SSR이 어떻게 동작하는지 이해하자.
router.get("/", async (_, res) => {
const movies = await fetchMovies();
const movieItems = parseMovieItems(movies);
const bestMovieItem = movieItems[0];
...
}
router.get("/", async (_, res) => {
...
const initData = /*html*/ `
<script>
window.__INITIAL_DATA__ = {
movies: ${JSON.stringify(movieItems)}
}
</script>
`;
...
});
router.get("/", async (_, res) => {
...
const renderedApp = renderToString(
<App popularMovies={movieItems} bestMovieItem={bestMovieItem} />
);
...
});
const router = Router();
router.get("/", async (_, res) => {
...
const templatePath = path.resolve(__dirname, "index.html");
const template = fs.readFileSync(templatePath, "utf-8");
...
});
router.get("/", async (_, res) => {
...
res.send(
template
.replace('<div id="root"></div>', `<div id="root">${renderedApp}</div>`)
.replace("<!--${INIT_DATA_AREA}-->", initData)
);
});
import React from "react";
import { hydrateRoot } from "react-dom/client";
import App from "./App";
const data = window.__INITIAL_DATA__;
hydrateRoot(
document.getElementById("root"),
<App popularMovies={data.movies} bestMovieItem={data.movies[0]} />
);
✅ 결과 코드
router.get("/", async (_, res) => {
const movies = await fetchMovies();
const movieItems = parseMovieItems(movies);
const bestMovieItem = movieItems[0];
const initData = /_html_/ `
<script>
window.__INITIAL_DATA__ = {
movies: ${JSON.stringify(movieItems)}
}
</script>
`;
const renderedApp = renderToString(
<App popularMovies={movieItems} bestMovieItem={bestMovieItem} />
);
const templatePath = path.resolve(\_\_dirname, "index.html");
const template = fs.readFileSync(templatePath, "utf-8");
res.send(
template
.replace('<div id="root"></div>', `<div id="root">${renderedApp}</div>`)
.replace("<!--${INIT_DATA_AREA}-->", initData)
);
});
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./static/styles/index.css" />
<title>영화 리뷰</title>
</head>
<body>
<div id="root"></div>
</body>
<!--${INIT_DATA_AREA}-->
</html>
import React from "react";
import { hydrateRoot } from "react-dom/client";
import App from "./App";
const data = window.__INITIAL_DATA__;
hydrateRoot(
document.getElementById("root"),
<App popularMovies={data.movies} bestMovieItem={data.movies[0]} />
);
webpack으로 번들링하면서 script 태그가 추가된 것을 확인할 수 있다.
댓글남기기