2024-03-29.md
๐กDIL: ๋ชจ๋ ๋ฆฌ์กํธ ๋ฅ ๋ค์ด๋ธ, 4์ฃผ์ฐจ-5
์คํฐ๋: ์๊ฐ CS, https://github.com/monthly-cs/2024-03-modern-react-deep-dive
์ค๋ ์งํ: ๊ฐ์ธ๊ณต๋ถ
DIL-week4-5_2024-03-29
| DIL ์ฃผ์ฐจ | ๋ฒ์ | ๋ด์ฉ | ์ค๋์ฐจ ์ง๋ | | -------- | ------ | ------------------------------- | ----------- | | 4์ฃผ์ฐจ | 4, 8์ฅ | SSR๊ณผ ESlint, ํ ์คํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ | 329p~335p |
์ค๋ ์ฝ์ ๋ด์ฉ์ markdown์ผ๋ก ๊ฐ๋จํ ๋ฉ๋ชจ
์ฝ์ ์๊ฐ: 12์ 50๋ถ ~ 1์๋ฐ
์ ๋ ์ฝ์ ์ด์ => ์ ์ฌ์๊ฐ ๊ณต๋ถ
Next.js ํบ์๋ณด๊ธฐ
_app.tsx ์์ฉํ๊ธฐ
- app.getInitialProps: context.ctx?.req?.url
import App, {AppContext} from 'next/app' import type {AppProps} from 'next/app' ... MyApp.getInitialProps = async (context: AppContext) => { const appProps = await App.getInitialProps(context) const isServer = Boolean(context.ctx.req) console.log( `[${isServer ? '์๋ฒ' : 'ํด๋ผ์ด์ธํธ'}] ${context.router.pathname}์์ ${context.ctx?.req?.url} ์์ฒญ` ) return appProps }
- ์คํ ์ ์ฐจ
| ์์ | ๋ก๊ทธ | ์ด์ |
| ----------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------ |
| ์์ฒด ํ์ด์ง getInitialProps๋ฅผ ๋ฐฉ๋ฌธ | [์๋ฒ] /test/GIP์์ /test/GIP๋ฅผ ์์ฒญ | ์๋ฒ ์ฌ์ด๋์ ๋๋๋ง ์ ์ฒด์ ์ผ๋ก ์๋ |
| getServerSideProps๊ฐ ์๋ ํ์ด์ง๋ฅผ
<Link>
๋ฅผ ์ด์ฉํ์ฌ ๋ฐฉ๋ฌธ | [์๋ฒ] /test/GSSP์์ /_next/data/~~/test/GSSP.json์ ์์ฒญ | ํ์ด์ง์ ์๋ฒ ๊ด๋ จ ๋ก์ง์ด ์๋๋ผ๋ json ํ์ผ๋ง์ ์์ฒญํ์ฌ ๊ฐ์ ธ์จ๋ค | | ๋ค์ 1๋ฒ์ ํ์ด์ง๋ฅผ<Link>
๋ฅผ ์ด์ฉํด์ ๋ฐฉ๋ฌธ | [ํด๋ผ์ด์ธํธ] /test/GSSP์์ undefined๋ฅผ ์์ฒญ | | | ๋ค์ 2๋ฒ์ ํ์ด์ง๋ฅผ<Link>
๋ฅผ ์ด์ฉํด์ ๋ฐฉ๋ฌธ | [์๋ฒ] /test/GSSP์์ /_next/data/~~/test/GSSP.json์ ์์ฒญ | ํด๋น ํ์ด์ง์ json ์์ฒญ (req.url์ด /_next๋ก ์์) | - ์ ์์ ์ธ ์ต์ด ํ์ด์ง ์ ๊ทผ
- req๊ฐ ์๋ค๋ฉด? ์๋ฒ๋ก ์ค๋ ์์ฒญ
- req.url์ด /_next๋ก ์์ํ์ง ์๋๋ค = ํด๋ผ์ด์ธํธ ๋๋๋ง์ผ๋ก ์ธํ ์์ฒญ์ด ์๋
- ์ ๊ทผ ์์ฒญํ๋ pathname์ด ์๋ฌ ํ์ด์ง๊ฐ ์๋
MyApp.getInitialProps = async (context: AppContext) => { const appProps = await App.getInitialProps(context); const { ctx: { req }, router: { pathname }, } = context; if ( req && // 1 !req.url?.startsWith("/_next") && // 2 !["/500", "/400", "/_error"].includes(pathname) // 2 ) { doSomethingOnlyOnce(); // ์ต์ด๋ก ์๋ฒ ์ฌ์ด๋ ๋๋๋ง์ ์ํํ์ ๋, ์ฝ๋๋ฅผ ์คํํ ์ ์๋ค } return appProps; };
Next.config.js
-
basePath: ์ ๊ทผ ๊ฐ๋ฅํ ์ฃผ์ (url prefix)
{ basePath: โdocsโ }
๋ ๋๋ฉ์ธ/docs ์์ ์๋น์ค ์์- ๋๋๋ง ์ ์ฃผ์์ basePath๊ฐ ๋ถ์ ์ฑ ํด๋ผ์ด์ธํธ ๋๋๋ง
- Next.js ์ ๊ณต ๊ธฐ๋ฅ์ด๋ฏ๋ก โ a, window.location.push์ ์ ์ฉ ์ ๋จ
-
powerByHeader: false
- ์๋ต ํค๋ X-Power-by: Next.js ์ ๋ณด ์ ๊ณต โ ๋ณด์ ๊ด์ ์์ ์ทจ์ฝ์ ์ด๋ฏ๋ก false๊ฐ ์ข๋ค
-
redirect ๋ฉ์๋: ์ ๊ท์ ์ฌ์ฉ ๊ฐ๋ฅ!
{ redirects() { return [ { // /tag/foo => /tag/foo/pages/1 source: '/tag/:tag', destination: '/tag/:tag/pages/1', permanent: true, }, { // /tag/foo/page/1 => /tags/foo/pages/1 source: '/tag/:tag/page/:no', destination: '/tags/:tag/pages/:no', permanent: true, }, { // /tags/foo/pages/something => /tags/foo/pages/1 source: '/tags/:tag/pages/((?!\\d).*)', destination: '/tags/:tag/pages/1', permanent: true } ] } }
-
reactStrictMode: ๋ฆฌ์กํธ ์๊ฒฉ ๋ชจ๋, default false์. true๋กค ๋ฆฌ์กํธ ์ ๋ฐ์ดํธ์ ๋๋น
-
assetPrefix: ๋์ผ ํธ์คํธ๊ฐ ์๋ CDN์ ์ ๋ก๋
- static ๋ฆฌ์์ค๋ค์ด ํด๋น ์ฃผ์ ์๋ค๊ณ ๊ฐ์ ex) ์ ์ ์ธ ๋ฆฌ์์ค๋ฅผ ๋ณ๋ CDN์ ์ ๋ก๋
assetPrefix: isProduction ? "https://cdn.somewhere.com" : undefined;