Create-React-App으로 SSR을 구현하며 배운 점 (feat. TypeScript)
Jun. 23, 2019•0 likes•3,149 views
Download to read offline
Report
Engineering
프로덕션 환경에서 클라이언트 사이드 렌더링을 고집하기란 힘든 일입니다. 서버를 통해 웹사이트를 제공하면서도 React의 편리함을 누리려면 서버 사이드 렌더링(SSR)을 구현해야 하는데요. Create-React-App을 그대로 유지하면서 SSR을 구현하는 과정을 보여드리고자 합니다. TypeScript로도 가능합니다!
3. • Server-Side Rendering?
• ImplementaDon
• Checklist
• 스파게티는 먹을 때에만 | 서버 코드를 분리하자
• asset-manifest.json | build 안에 담긴 보물
• 직선보다 빠른 굴절 | TypeScript를 사용하는 편이 좋은 이유
• Extra
• 필수 패키지 설치 이슈
13. render | hydrate
전체 HTML
렌더링
기존 HTML과 비교 후
부분 업데이트
ReactDOM.hydrate(<App />, document.getElementById('root'));
14. Checklist
스파게티는 먹을 때에만 | 서버 코드를 분리하자
asset-manifest.json | build 안에 담긴 보물
직선보다 빠른 굴절 | TypeScript를 사용하는 편이 좋은 이유
15. 스파게티는
먹을 때에만
renderToString() 함수가 서버 코드와 섞이기
마련
bootstrap.js 파일을 추가로 작성해 각자의 코드
를 따로 불러올 것
git submodule 운용 가능
Server Client
bootstrap.js
express app
객체
renderToString()
결과물
app.listen() ...
16. Bad
export default () => {
const app: express.Application = express();
const router: express.Router = express.Router();
router.use('^/$', (req, res) => {
const html = ReactDOMServer.renderToString(<App />);
...
});
...
};
서버 코드 안에서
React를 직접 호출
Front - Server
지나친 커플링
21. asset-
manifest.json
build 폴더에 생성된 모든 자산의 일람표
html string을 만들 때 staDc file의 참조를 가져다
쓸 수 있다
asset-
manifest.json
<img
src={logo}
className="App-logo"
alt="logo"
/>
+
"/static/media/logo.5d5d9eef.svg"
<img
src="/static/media/logo.5d5d9eef.svg"
class="App-logo"
alt="logo"
/>
31. Redux
서버 렌더링 단계에서 데이터를 미리 주입하고 싶을
때만 사용
index.html에 인라인으로 window 전역 store
객체 삽입 -> 클라이언트 코드가 읽어들임
(공식 문서에서 권하는 방식)
https://redux.js.org/recipes/server-
rendering
<script>
window.__PRELOADED_STATE__={}
</script>
+
32. React-
Router-
DOM
html 생성 단계에서 StaticRouter 를 App 위에
Wrapping
서버 또한'*' 경로 라우터를 추가해 react-router
가 만든 path로 접속되더라도 html을 반환하도록 처
리
// server/index.ts
router.use('*', htmlRenderer);
// src/html.tsx
const routerContext = {};
<StaticRouter
location={req.baseUrl}
context={routerContext}
>
<App />
</StaticRouter>
33. React-
Loadable
모듈 이름을 특정해줘야
서버 렌더링 시에 모듈 추적을 할 수 있음!
const Index = Loadable({
loader: () => import(/* webpackChunkName: "IndexChunk" */
'../components/view/index'),
loading: () => null,
modules: ['IndexChunk'],
});