# ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์ด๋ž€?

์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์ด๋ž€ ์„œ๋ฒ„์—์„œ ํŽ˜์ด์ง€๋ฅผ ๊ทธ๋ ค ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)๋กœ ๋ณด๋‚ธ ํ›„ ํ™”๋ฉด์— ํ‘œ์‹œํ•˜๋Š” ๊ธฐ๋ฒ•์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๋ทฐ ์‹ฑ๊ธ€ ํŽ˜์ด์ง€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์˜ ๋ฐ˜๋Œ€์ธ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ดํŠธ ๋ Œ๋”๋ง๊ณผ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง ๋ฐฉ์‹์˜ ์ฐจ์ด์ ์„ ์‚ดํŽด๋ณด๊ณ  ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์˜ ์žฅ๋‹จ์ ์„ ๋ถ„์„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

# ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง

ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ทฐ CLI๋กœ ์ƒ์„ฑ๋œ ํ”„๋กœ์ ํŠธ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ๋ทฐ CLI๋กœ ์ƒ์„ฑํ•œ ํ”„๋กœ์ ํŠธ์˜ ๊ธฐ๋ณธ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

// src/main.js
import Vue from "vue";
import App from "./App.vue";

new Vue({
  render: (h) => h(App),
}).$mount("#app");

์œ„ ์ฝ”๋“œ๋Š” ๋ทฐ์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์ด ์ธ์Šคํ„ด์Šค๋Š” ์•„๋ž˜ index.html ํŒŒ์ผ์˜ app ์•„์ด๋””๋ฅผ ๊ฐ–๋Š” ํƒœ๊ทธ์— ๋ถ€์ฐฉ๋ฉ๋‹ˆ๋‹ค.











ย 




<!-- public/index.html -->
<!DOCTYPE html>
<html lang="">
  <head>
    <!-- ... -->
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

CLI๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋‚œ ํ›„ npm run serve๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ™•์ธํ•˜๋ฉด ๋ทฐ ๊ธฐ๋ณธ ํŽ˜์ด์ง€๊ฐ€ ๋œน๋‹ˆ๋‹ค. ์ด ๋•Œ ๊ฐœ๋ฐœ์ž ํŒจ๋„์˜ Network ํƒญ์—์„œ Doc์œผ๋กœ ํ•„ํ„ฐ๋งํ•œ ๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

csr-result

์„œ๋ฒ„์—์„œ ๋„˜๊ฒจ๋ฐ›์€ HTML ์ฝ”๋“œ์—๋Š” body ํƒœ๊ทธ ๋ณธ๋ฌธ์— <div id="app"></div> ๋ฐ–์— ์—†์ง€๋งŒ ํ™”๋ฉด์—๋Š” Welcome To Your Vue.js App ํ…์ŠคํŠธ์™€ ์ด๋ฏธ์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ…์ŠคํŠธ์™€ ์ด๋ฏธ์ง€๋Š” ๋ชจ๋‘ ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)์—์„œ ๋™์ž‘ํ•œ Vue.js ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๊ทธ๋ ค์ค€ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ฆ‰ ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ™”๋ฉด์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋ ค๋‚ธ ๊ฒƒ์ด์ฃ .

# ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง๊ณผ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง ์ฐจ์ด์ 

๊ทธ๋Ÿผ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ์˜ ๋ Œ๋”๋ง์€ ์•ž์—์„œ ์‚ดํŽด๋ณธ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง๊ณผ ๋ฌด์Šจ ์ฐจ์ด์ ์ด ์žˆ์„๊นŒ์š”? ๋ฐ”๋กœ ์–ด๋””์„œ ํ™”๋ฉด์— ๋ณด์ผ ํŽ˜์ด์ง€์˜ ๋‚ด์šฉ์„ ๊ทธ๋ฆฌ๋Š๋ƒ์˜ ์ฐจ์ด์ž…๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์€ ํŽ˜์ด์ง€์˜ ๋‚ด์šฉ์„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ทธ๋ฆฌ๊ณ  ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์€ ์„œ๋ฒ„์—์„œ ํŽ˜์ด์ง€์˜ ๋‚ด์šฉ์„ ๋‹ค ๊ทธ๋ ค์„œ ๋ธŒ๋ผ์šฐ์ €๋กœ ๋˜์ ธ์ค๋‹ˆ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๋ง์ด์ฃ .

ssr-vs-csr

# ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์„ ์™œ ์“ธ๊นŒ?

์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์„ ์“ฐ๋Š” ๋ชฉ์ ์€ ํฌ๊ฒŒ "๊ฒ€์ƒ‰ ์—”์ง„ ์ตœ์ ํ™”"์™€ "๋น ๋ฅธ ํŽ˜์ด์ง€ ๋ Œ๋”๋ง"์ž…๋‹ˆ๋‹ค. ๊ฒ€์ƒ‰ ์—”์ง„ ์ตœ์ ํ™”๋ž€ ๊ตฌ๊ธ€, ๋„ค์ด๋ฒ„์™€ ๊ฐ™์€ ๊ฒ€์ƒ‰ ์‚ฌ์ดํŠธ์—์„œ ๊ฒ€์ƒ‰ํ–ˆ์„ ๋•Œ ๊ฒฐ๊ณผ๊ฐ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋งŽ์ด ๋…ธ์ถœ๋  ์ˆ˜ ์žˆ๋„๋ก ์ตœ์ ํ™” ํ•˜๋Š” ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค. ํŠนํžˆ, SNS์—์„œ ๋งํฌ๋ฅผ ๊ณต์œ ํ–ˆ์„ ๋•Œ ํ•ด๋‹น ์›น ์‚ฌ์ดํŠธ์˜ ์ •๋ณด๋ฅผ ์ด๋ฏธ์ง€์™€ ์„ค๋ช…์œผ๋กœ ํ‘œ์‹œํ•ด์ฃผ๋Š” OG(Open Graph) Tag๋ฅผ ํŽ˜์ด์ง€ ๋ณ„๋กœ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์ด ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.

og-tag

๋˜ํ•œ, ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์€ ๋นˆ HTML ํŽ˜์ด์ง€๋ฅผ ๋ฐ›์•„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๊ทธ๋ฆฌ๋Š” ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง๊ณผ ๋‹ค๋ฅด๊ฒŒ ์„œ๋ฒ„์—์„œ ๋ฏธ๋ฆฌ ๊ทธ๋ ค์„œ ๋ธŒ๋ผ์šฐ์ €๋กœ ๋ณด๋‚ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ํŽ˜์ด์ง€๋ฅผ ๊ทธ๋ฆฌ๋Š” ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ๋Š” ํ™”๋ฉด์— ์œ ์˜๋ฏธํ•œ ์ •๋ณด๊ฐ€ ํ‘œ์‹œ๋˜๋Š” ์‹œ๊ฐ„์ด ๋นจ๋ผ์ง€๋Š” ๊ฒƒ์ด์ฃ .

# ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์˜ ๋‹จ์ 

์ด๋ ‡๊ฒŒ๋งŒ ๋ณด๋ฉด ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์„ ํ•˜๋Š”๊ฒŒ ์ข‹๊ฒ ๋„ค ๋ผ๊ณ  ์ƒ๊ฐํ•˜์‹ค ์ˆ˜ ์žˆ์ง€๋งŒ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์€ Node.js ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ๋ฐฉ๋ฒ•์„ ์•Œ์•„์•ผํ•˜๊ณ  ์„œ๋ฒ„์ชฝ ํ™˜๊ฒฝ ๊ตฌ์„ฑ๊ณผ ํ•จ๊ป˜ ํด๋ผ์ด์–ธํŠธ, ์„œ๋ฒ„ ๋นŒ๋“œ์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ, ํ”„๋ŸฐํŠธ์—”๋“œ ๊ฐœ๋ฐœ ์ž…๋ฌธ์ž ์ž…์žฅ์—์„œ๋Š” ์‰ฝ์ง€ ์•Š์€ ์ง„์ž… ์žฅ๋ฒฝ์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, Node.js ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ธŒ๋ผ์šฐ์ € ๊ด€๋ จ API๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ์ฃผ์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ทฐ ์‹ฑ๊ธ€ ํŽ˜์ด์ง€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ผ์ดํ”„์‚ฌ์ดํด ํ›…๊ณผ๋Š” ๋‹ค๋ฅธ ํ™˜๊ฒฝ(๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์•„๋‹Œ Node.js)์—์„œ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— beforeCreate์™€ created์—์„œ window๋‚˜ document์™€ ๊ฐ™์€ ๋ธŒ๋ผ์šฐ์ € ๊ฐ์ฒด์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

document-access-error

TIP

์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง์˜ ๊ฒฝ์šฐ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ตœ์ดˆ๋กœ ์ƒ์„ฑ๋˜๋Š” ์‹œ์ ์ด ๋ธŒ๋ผ์šฐ์ € ์œ„๊ฐ€ ์•„๋‹ˆ๋ผ Node.js ํ™˜๊ฒฝ์ด๊ธฐ ๋•Œ๋ฌธ์— beforeCreate๋‚˜ created์—์„œ ๋ธŒ๋ผ์šฐ์ € ๊ฐ์ฒด๋ฅผ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  beforeMount๋‚˜ mounted์—์„œ window์™€ document๋ฅผ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿ˜ƒ

# ์˜จ๋ผ์ธ ๊ฐ•์˜๋กœ ์‰ฝ๊ฒŒ ๋ฐฐ์šฐ๋Š” ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๋ Œ๋”๋ง