# μ„œλ²„ μ‚¬μ΄λ“œ λ Œλ”λ§μ΄λž€?

μ„œλ²„ μ‚¬μ΄λ“œ λ Œλ”λ§μ΄λž€ μ„œλ²„μ—μ„œ νŽ˜μ΄μ§€λ₯Ό κ·Έλ € ν΄λΌμ΄μ–ΈνŠΈ(λΈŒλΌμš°μ €)둜 보낸 ν›„ 화면에 ν‘œμ‹œν•˜λŠ” 기법을 μ˜λ―Έν•©λ‹ˆλ‹€. λ·° μ‹±κΈ€ νŽ˜μ΄μ§€ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ μ„œλ²„ μ‚¬μ΄λ“œ λ Œλ”λ§μ˜ λ°˜λŒ€μΈ ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄λ“œ λ Œλ”λ§ λ°©μ‹μž…λ‹ˆλ‹€. 이 κΈ€μ—μ„œλŠ” ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄νŠΈ λ Œλ”λ§κ³Ό μ„œλ²„ μ‚¬μ΄λ“œ λ Œλ”λ§ λ°©μ‹μ˜ 차이점을 μ‚΄νŽ΄λ³΄κ³  μ„œλ²„ μ‚¬μ΄λ“œ λ Œλ”λ§μ˜ μž₯단점을 뢄석해 λ³΄κ² μŠ΅λ‹ˆλ‹€.

# ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄λ“œ λ Œλ”λ§

ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄λ“œ λ Œλ”λ§μ„ μ΄ν•΄ν•˜κΈ° μœ„ν•΄μ„œ λ·° 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λ₯Ό μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€ πŸ˜ƒ

# 참고 자료