코드 확인
https://github.com/insidedw/react-webpack5-ssr/commit/1d97ecbcb6681db250940cf52cdf90411e171a9a
integrate react-router-dom · insidedw/react-webpack5-ssr@1d97ecb
insidedw committed Jul 7, 2024
github.com
의존성 설치
npm i react-router-dom
client.js 수정
client side 부터 설정해보자.
SSR이니 hash보단 browser router로
import React from 'react'
import ReactDOM from 'react-dom'
import App from './components/App'
import { BrowserRouter } from 'react-router-dom'
ReactDOM.hydrate(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root'),
)
App.js 수정
path 마다 다른 마크업 적용.
csr를 확인해보기 위해 link 태그 추가
import React from 'react'
import './App.css'
import { Link, Route, Routes } from 'react-router-dom'
const App = () => {
return (
<Routes>
<Route
path={'/'}
element={
<div>
<h1>Hello, SSR!</h1>
<Link to={'/about'}>About</Link>
</div>
}
/>
<Route
path={'/about'}
element={
<div>
<h1>SSR is sever side rendering</h1>
<Link to={'/'}>Home</Link>
</div>
}
/>
</Routes>
)
}
export default App
실행해보면 다음과 같은 에러가 노출된다.
이유는 ssr에서 route 컴포넌트를 읽을 때 에러가 나기 때문이다.
csr에서는 BrowserRouter로 감싸줬지만, ssr에서는 감싸주는 컴포넌트가 없기 때문이다.
Error: useRoutes() may be used only in the context of a <Router> component.
at Object.invariant [as UNSAFE_invariant] (C:\Users\USER\IdeaProjects\react-ssr\node_modules\@remix-run\router\dist\router.cjs.js:315:11)
at useRoutesImpl (C:\Users\USER\IdeaProjects\react-ssr\node_modules\react-router\dist\umd\react-router.development.js:348:36)
at useRoutes (C:\Users\USER\IdeaProjects\react-ssr\node_modules\react-router\dist\umd\react-router.development.js:343:12)
at Routes (C:\Users\USER\IdeaProjects\react-ssr\node_modules\react-router\dist\umd\react-router.development.js:1232:12)
at renderWithHooks (C:\Users\USER\IdeaProjects\react-ssr\node_modules\react-dom\cjs\react-dom-server-legacy.node.development.js:5662:16)
at renderIndeterminateComponent (C:\Users\USER\IdeaProjects\react-ssr\node_modules\react-dom\cjs\react-dom-server-legacy.node.development.js:5736:15)
at renderElement (C:\Users\USER\IdeaProjects\react-ssr\node_modules\react-dom\cjs\react-dom-server-legacy.node.development.js:5961:7)
at renderNodeDestructiveImpl (C:\Users\USER\IdeaProjects\react-ssr\node_modules\react-dom\cjs\react-dom-server-legacy.node.development.js:6119:11)
at renderNodeDestructive (C:\Users\USER\IdeaProjects\react-ssr\node_modules\react-dom\cjs\react-dom-server-legacy.node.development.js:6091:14)
at renderIndeterminateComponent (C:\Users\USER\IdeaProjects\react-ssr\node_modules\react-dom\cjs\react-dom-server-legacy.node.development.js:5790:7)
server.js 수정
https://reactrouter.com/en/main/guides/ssr#without-a-data-router 가이드에 따라 코드 추가
import path from 'path'
import fs from 'fs'
import React from 'react'
import express from 'express'
import { renderToString } from 'react-dom/server'
import App from './components/App'
import { StaticRouter } from 'react-router-dom/server'
const app = express()
app.use(express.static('dist'))
const html = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React SSR</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
`
const manifest = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../dist/manifest.json'), 'utf8'))
const scripts = Object.keys(manifest)
.filter((key) => key.endsWith('.js'))
.map((key) => `<script defer src="${manifest[key]}"></script>`)
.join('\n')
const styles = Object.keys(manifest)
.filter((key) => key.endsWith('.css'))
.map((key) => `<link rel="stylesheet" type="text/css" href="${manifest[key]}">`)
.join('\n')
app.get('*', (req, res) => {
const appString = renderToString(
<StaticRouter location={req.url}>
<App />
</StaticRouter>,
)
return res.send(
html
.replace('<div id="root"></div>', `<div id="root">${appString}</div>`)
.replace('</head>', `${styles}</head>`)
.replace('</body>', `${scripts}</body>`),
)
})
app.listen(3000, () => {
console.log('Server is listening on port 3000')
})
테스트 후 잘 동작하는 걸 확인 할 수 있다.
'IT > react' 카테고리의 다른 글
[react] ssr 프로젝트 만들기 (6) - stream으로 html 그리기, 추가 설명 (0) | 2024.07.13 |
---|---|
[react] ssr 프로젝트 만들기 (5) - stream으로 html 그리기 (0) | 2024.07.08 |
[react] ssr 프로젝트 만들기 (3) - css, js 번들에 hash 추가 (0) | 2024.07.02 |
[react] ssr 프로젝트 만들기 (2) - css, 번들에 추가하기 (0) | 2024.07.02 |
[react] ssr 프로젝트 만들기 (1) - hello world 찍기 (0) | 2024.07.01 |