์ด์ ๊ธ์์ CSR, SSR, SSG์ ๋ํด ๊ฐ๊ฐ์ ์ฐจ์ด์ ์ ๋ํด์ ๋ค๋ค ๋ณด์์ต๋๋ค. Angular, React, Vue์์ ๊ฐ๊ฐ์ ๋ฐฉ์์ผ๋ก ์ด๋ฌํ ๋ ๋๋ง ๋ฐฉ์์ผ๋ก ๊ตฌํ์ ํ ์๊ฐ ์๋๋ฐ์. ๋ํ์ ์ผ๋ก Angular๋ Universal, React๋ NextJs, Vue๋ Nuxt ๋ฑ์ ๋ง์ด ์ฌ์ฉํ๋ ๊ฒ ๊ฐ๋ค์. Angular๋ ๊ตญ๋ด์์ ์ธ๊ธฐ๊ฐ ๋ง์ด ์์ด์์ธ์ง ํด๋น ๋ด์ฉ์ ๋ค๋ฃจ๋ ๊ธ์ด ์๋๋ฏํ์ฌ ์ด๋ฒ ๊ธฐํ์ ์ ๊ฐ ์ฌ์ฉ์ ํด๋ณด๊ณ ๊ฐ๋จํ๊ฒ๋๋ง ์ ๋ฆฌํด๋ณด๊ฒ ์ต๋๋ค.
๋ ๋๋ง ์ข ๋ฅ์ ๋ํ ๊ธ์ ์ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ
๊ฒฐ๋ก ๋ถํฐ ๋ง์๋๋ฆฌ๋ฉด ๊ต์ฅํ ์ฝ์ต๋๋ค!
๋จผ์ ๊ฐ๋จํ๊ฒ ๊ฐ๋ ์ ๋๋ง ๋ค์ ์ง๊ณ ๋์ด๊ฐ๊ฒ ์ต๋๋ค.
PreRendering
์ฐ๋ฆฌ์๊ฒ ๊ฐ์ฅ ์ต์ํ ํด๋ผ์ด์ธํธ ๋ ๋๋ง(CSR) ๋ฐฉ์์ ์ ์์ค ํ ๊ณ , ์๋ฒ์ฌ์ด๋ ๋ ๋๋ง(SSR)์ ๊ฐ ํ์ด์ง์ ๋ํ ์์ฒญ์ ๋ฐ์ผ๋ฉด ๋ธ๋ผ์ฐ์ ์์ง์ ๋์ ํด์ ์๋ฒ์์ Node๊ฐ ๋ ๋๋งํ๊ณ ๊ฒฐ๊ณผ๋ฌผ์ ํด๋ผ์ด์ธํธ์์ ์ ๋ฌํด์ฃผ๋ ๊ฒ์ด๊ณ , ์ฌ์ ๋ ๋๋ง(PreRendering, SSG) ๋ง ๊ทธ๋๋ก ๋ฏธ๋ฆฌ ๋ ๋๋ง์ ํด๋๊ณ ์๋ฒ์์ ํด๋น ํ์ด์ง์ ๋ํ ์์ฒญ์ด ์ค๋ฉด ๋ฏธ๋ฆฌ ๋ ๋๋งํด๋์๋ ํ์ด์ง๋ฅผ ์ ๋ฌ!
์ ์ด์ ๋๊ตฌ๋ ์๋ ค์ฃผ์ง ์์๋, Angular Universal์ ์ด์ฉํด ํ์ด๋ธ๋ฆฌ๋ ๋ ๋๋ง์ ๊ตฌํํด ๋ณด๊ฒ ์ต๋๋ค.
Universal
hybrid-rendering-app
์ด๋ผ๋ ์๋ก์ด ํ๋ก์ ํธ๋ฅผ ์์ฑํ๊ณ universal package๋ฅผ ์ถ๊ฐํด์ค๋๋ค.
ng new hybrid-rendering-app
ng add @nguniversal/express-engine
@nguniversal/express-engine
์ ์ถ๊ฐ ํด์ฃผ๋ฉด main.server.ts
, app.server.module.ts
๊ณผ ๊ฐ์ ๋ญ๊ฐ ๋ชป๋ณด๋ ํ์ผ๋ค์ด ์๊ฒจ๋๋ ๊ฒ์ ๋ณด์ค์ ์์ต๋๋ค. ์ฐ๋ฆฌ๋ ์ง๊ธ๊ป ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ํด๋ผ์ด์ธํธ ๋ ๋๋ง์ ์ฌ์ฉํ์ง๋ง, ์ด์ ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์ด ์๋๊ณณ์์ ๋ ๋๋ง์ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ Node๊ฐ ์คํํด์ค ํ์ผ์ด ํ์ํ๊ธฐ ๋๋ฌธ์
๋๋ค.
package.json
ํ์ผ์ ๋ณด๋ฉด ์ฒ์ ๋ณด๋ scripts๋ค๋ ํ์ธ ํ ์ ์์ต๋๋ค.
"dev:ssr": "ng run hybrid-rendering-app:serve-ssr",
"serve:ssr": "node dist/hybrid-rendering-app/server/main.js",
"build:ssr": "ng build && ng run hybrid-rendering-app:server",
"prerender": "ng run hybrid-rendering-app:prerender"
ํค๊ฐ๋ช ์นญ์ ๋ณด๋ฉด ๋์ถฉ ์ด๋ค๊ฒ์ ํ๋๊ฒ์ด๊ฒ ๊ตฌ๋.. ํ๋ ์ ๋์ ๊ฐ์ ์ค์ จ์ ๊ฒ๋๋ค.
๋จผ์ prerendering
์ ํด๋ณด๊ธฐ ์ํด route ํ์ด์ง๊ฐ ํ์ํ๋ฐ, about์ contact ๋ชจ๋์ ์ถ๊ฐํ๊ณ ๋ผ์ฐํฐ์ ๋ฑ๋ก ์์ผ๋ณด๊ฒ ์ต๋๋ค.
๊ฐ๊ฐ์ ์ปดํฌ๋ํธ๋ฅผ ์์ฑํด router์ ๋ฑ๋กํด๋ ๋์ง๋ง ์๋์ ๊ฐ์ ๋ช ๋ น์ด๋ฅผ ํตํด ์ฝ๊ฒ ์ถ๊ฐํ ์ ์์ต๋๋ค. (Angular ํ๋ ์์์ ์ฅ์ ์ด๊ธฐ๋ ํ์ฃ , ๋ณต์กํด ๋ณด์ด์ง๋ง ์ฒด๊ณ์ ์ด๋ค? ^^;)
ng g m about --route about --module app
ng g m contact --route contact --module app
Run
๋ฐ๋ก ์ฌ์ ๋ ๋๋ง์ ํด๋ณด์ฃ !
npm run prerender
dist ๋๋ ํ ๋ฆฌ๋ฅผ ๋ณด์๋ฉด server, browser ๋๊ฐ์ ๋๋ ํ ๋ฆฌ๋ก ๋๋์ด์ ธ ์๋ค์. server/main.js ์ด ํ์ผ์ด node์์ ์คํํด์ฃผ๋ ํ์ผ์ด ๋๋๊ฒ์ด๊ณ ์, browser ๋๋ ํ ๋ฆฌ ๋ด๋ถ์ ์๋ ํ์ผ๋ค์ด ๋ ๋๋ง๋ ํ์ผ๋ค์ ๋๋ค. ๊ทธ๋ฐ๋ฐ index.html ํ์ผ๋ง ์๋๊ฒ ์๋๊ณ router์ ๋ฑ๋กํ about, contact์ index.htmlํ์ผ๋ ๊ฐ๊ฐ์ ๋๋ ํ ๋ฆฌ์ ์์ฑ์ด ๋์์ต๋๋ค. ๊ฐ๊ฐ์ ํ์ด์ง ์์ฒญ์ด ์ค๋ฉด ๋ฏธ๋ฆฌ ๋๋๋งํด๋ index.htmlํ์ผ์ ์ ๋ฌํ๊ธฐ ์ํจ์ด์ฃ .
Options
๊ทธ๋ฆฌ๊ณ angular.json
ํ์ผ์ ์ต์
์ ๋ณด๋ฅผ ์ด์ฉํด์ ์ํ๋ ํ์ด์ง๋ง ์ฌ์ ๋ ๋๋ง์ ํด๋์๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด about ํ์ด์ง๋ง ์ฌ์ ๋ ๋๋ง์ ํด๋๊ณ ์ถ๋ค. ๊ทธ๋ผ "guessRoutes": false
, "routes"
๋ฐฐ์ด์ ๋ ๋๋งํ ํ์ด์ง๋ง ์ถ๊ฐํด์ค๋๋ค.
projects > hybrid-rendering-app > architect > prerender
"options" : {
"guessRoutes": false,
"routes": [
"/about"
]
}
"routesFile": "./routes.txt" ํ์ผ์ ๊ฒฝ๋ก๋ค์ ์ค์ ํ ์๋ ์์ต๋๋ค.
๋ ์์ธํ options
์ ๋ณด๋ ์ฌ๊ธฐ์์ ํ์ธํด ์ฃผ์ธ์
์ด์ node๋ก ํด๋น jsํ์ผ์ ์คํํด์ฃผ๋ฉด ๋ฉ๋๋ค.
Server Start
node dist\hybrid-rendering-app\server\main.js
Node Express server listening on http://localhost:4000
์๋ฒ๋ฅผ ๊ตฌ๋ํด์ฃผ๊ณ ๋ธ๋ผ์ฐ์ ์ ์ ์ํด์ Network ํญ์ ์ดํด ๋ณด๋ฉด ๊ฐ ๋ผ์ฐํ ์ ์ ๊ทผํ ๋๋ง๋ค ํด๋น ๋ฌธ์๋ฅผ ๋ค์ด๋ฐ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
main
about
contact
์ต์ด ์ ์์ index.html ํ์ผ์ ๋ฐ์ ๊ทธ์์์ javascript ํ์ผ์ ์ํด ๋์ ์ผ๋ก ๋ฌธ์๋ฅผ ๋ณ๊ฒฝํ๋ SPA๋ฐฉ์๊ณผ๋ ๋ฌ๋ฆฌ ๋ผ์ฐํฐ ์ ๊ทผ์ ์ฌ์ ์ ๋ ๋๋ง๋ ๋ฌธ์๋ฅผ ์๋ฒ์์ ์ ๋ฌํด์ฃผ๊ฒ ๋ฉ๋๋ค.
๊ฑฐ์ ๋ณ๊ฒฝ์ด ์๋ ํ์ด์ง๋ค์ ๊ฒฝ์ฐ ์ด๋ ๊ฒ ์ฌ์ ์ ๋ ๋๋ง์ ํด๋๋ฉด ์ฑ๋ฅ์ ์ธ ๋ถ๋ถ์์ ๋งค์ฐ ํจํผ์ ์ผ ๊ฒ์ด์ง๋ง, ํ์ด์ง ๋ด์ฉ์ด ์์ฃผ ๋ณ๊ฒฝ์ด ๋๋ค๊ฑฐ๋ ๊ฒ์ํ ๊ฐ์ ๋์ ์ธ ๋ผ์ฐํ
์ ์ฌ์ฉํ๋ค๋ฉด, options
์ ๋ ๋๋งํ ํ์ด์ง๋ง ๋ช
์ํด์ฃผ๋ฉด ์ ํ์ ์ผ๋ก ์ฌ์ ๋ ๋๋ง์ ํ ์ ์๊ฒ ๋๋ ๊ฒ ์
๋๋ค.