2022. 5. 17. 21:28ใFront-End ์์ ์ค/Nuxt.js
Git Hub
๐ ๋ชฉ์ฐจ
โ [Vue+Nuxt.js] Nuxt.js ๊ธฐ๋ณธ
โ[Vue+Nuxt.js] Nuxt.js ์์ํ๊ธฐ
โ [Vue+Nuxt.js] Nuxt.js Data ํธ์ถ ๋ฐฉ์๊ณผ API ์ฐ๋
โ[Vue+Nuxt.js] Nuxt.js๋ฅผ ์ด์ฉํ์ฌ ์ผํ ์ํ ๋ชฉ๋ก ํ์ด์ง์ ์์ธ ํ์ด์ง ๊ฐ๋ฐ
โ [Vue+Nuxt.js] Nuxt.js๋ฅผ ์ด์ฉํ์ฌ ์ผํ ์ํ ๊ฒ์ UI ๊ฐ๋ฐ
โ[Vue+Nuxt.js] Vuex๋ฅผ ์ด์ฉํ์ฌ ์ฅ๋ฐ๊ตฌ๋ Page ๋ง๋ค๊ธฐ
โ [Vue+Nuxt.js] Vuex ์๋ก๊ณ ์นจ ์ ์ด๊ธฐํ ๋๋ ๋ฌธ์ ํด๊ฒฐ
๐ ๋ถ๋ก
โ [FrontEnd] HMR(Hot Module Replacement)
โ [Nuxt.js] ๋น๋๊ธฐ ๋ฐ์ดํฐ ํธ์ถ ๋ฐฉ๋ฒ
โ V-Model ๋์ ์๋ฆฌ์ ํ์ฉ ๋ฐฉ๋ฒ
โ [Nuxt.js] NuxtServerInit
๐ ๋ด๊ฐ ๋ง๋ Error
โ [vuex] expects string as the type, but found undefined.
๐ Nuxt.js๋?
๐ฝ ๊ฐ์
Nuxt๋ Vue.js์ Framework์ ๋๋ค.
Vue.js๋ JavaScript์ Framework์ธ๋ฐ, ์ด๊ฒ์ ๋ Framework๋ฅผ ์ฌ์ฉํ๋ค๋ผ๊ณ ๋ณด๋ฉด ๋๋ ๊ฒ์ด์์.
์ฐธ๊ณ ๋ก Framework์ Library์ ๊ฐ๋จํ ์ฐจ์ด์ ์ ์ผ๋ง๋ ์์ ๋๊ฐ ๋๋์ธ๋ฐ, Framework๊ฐ ์์ ๋๊ฐ ๋ฎ์ ํธ์ด๊ณ , ๊ทธ ๋ง์ธ ์ฆ, ์ ํด์ ธ ์๋ ๊ฒ์ด ๋ง์ ๊ฐ์ ธ๋ค๊ฐ ์ฐ๊ธฐ๋ง ํ๋ฉด ๋๋ค๋ ์๋ฏธ๊ฐ ๋๋ ๊ฒ์ ๋๋ค.
Nuxt๋ Vue.js๋ก ๋น ๋ฅด๊ฒ ์น์ ์ ์ํ ์ ์๊ฒ ๋์์ฃผ๋ ํ๋ ์์ํฌ์ธ๋ฐ, ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ํ ๋ ํ์ํ Vuex, Router, Axios์ ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ๋ฏธ๋ฆฌ ๊ตฌ์ฑํ์ฌ ์ฑ๊ธ ํ์ด์ง ์ ํ๋ฆฌ์ผ์ด์ (Single Page Application), ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง(Server Side Rendering), ์ ์ ์น ์ฌ์ดํธ(Static Generated Website)๋ฅผ ์ฝ๊ฒ ์ ์ํ ์ ์๊ฒ ํด์ฃผ๋ ๋๊ตฌ์ธ ๊ฒ์ด์์.
๐ก ์ฐธ๊ณ ์ฌํญ
Server Side Rendering์ด๋? ์น ํ์ด์ง์ ๋ด์ฉ์ ์๋ฒ์์ ๋ชจ๋ ์์ฑํด์ ํด๋ผ์ด์ธํธ(๋ธ๋ผ์ฐ์ )๋ก ๋ณด๋ธ ๋ค ํ๋ฉด์ ๊ทธ๋ฆฌ๋ ๋ฐฉ์.
๐ฝ ํน์ง
Nuxt.js์ ํน์ง์ ์์ฝํ๋ฉด ์๋์ ๊ฐ์ด ๋๋ ์ ์์ต๋๋ค.
โ ์๋ฒ ์ฌ์ด๋ ๋๋๋ง ๋ฐฉ์
โ ๊ท๊ฒฉํ๋ Packge(ํด๋) ๊ตฌ์กฐ (layout, sotre, middleware, plugins ๋ฑ)
โ pages ํด๋ ๊ธฐ๋ฐ ์๋ ๋ผ์ฐํ
์ค์
โ ์ฝ๋ ์คํ๋ฆฌํ
โ ๋น๋๊ธฐ ๋ฐ์ดํฐ ์์ฒญ ์์ฑ
โ ES6/ES6+ ๋ณํ
โ ์นํฉ์ ๋น๋กฏํ ๊ธฐํ ์ค์
๐ฝ Server Side Rendering
๐ฆ ๊ฐ์
Vue Single Page Application์ Server Side Rendering์ ๋ฐ๋ ๊ฐ๋ ์ธ Client Side Rendering ๋ฐฉ์์ธ ๊ฒ์ด์์.
Server Side Rendering ๋ฐฉ์์ ์์ ๋ถํฐ ์ด์ด์ ธ ๋ด๋ ค์ค๋ ์ ๋๋ํ์ ๊ฐ์ด ์ค๋์ ๋ถํฐ ์ฌ์ฉ๋๋ ๊ธฐ๋ฒ์ด์์.
๐ฆ ์ฌ์ฉํ๋ ์ด์
์๋ฒ ์ฌ์ด๋ ๋ฐฉ์์ ์ฐ๋ ๋ชฉ์ ์ ํฌ๊ฒ `๊ฒ์ ์์ง ์ต์ ํ`์ `๋น ๋ฅธ ํ์ด์ง ๋๋๋ง`์ ์ํด์ ์
๋๋ค.
๊ฒ์ ์์ง ์ต์ ํ๋ ๊ตฌ๊ธ, ๋ค์ด๋ฒ์ ๊ฐ์ ๊ฒ์ ์ฌ์ดํธ์์ ๊ฒ์ํ์ ๋ ๊ฒฐ๊ณผ๊ฐ ์ด์ฉ์์๊ฒ ๋ง์ด ๋
ธ์ถ๋ ์ ์๋๋ก ์ต์ ํ ํ๋ ๊ธฐ๋ฒ์ธ ๊ฒ์ด์์. ํนํ, SNS์์ ๋งํฌ๋ฅผ ๊ณต์ ํ์ ๋ ํด๋น ์น ์ฌ์ดํธ์ ์ ๋ณด๋ฅผ ์ด๋ฏธ์ง์ ์ค๋ช
์ผ๋ก ํ์ํด์ฃผ๋ OG(Open Graph) Tag๋ฅผ Page ๋ณ๋ก ์ ์ฉํ๊ธฐ ์ํด์๋ ์๋ฒ ์ฌ์ด๋ ๋๋๋ง์ด ํจ์จ์ ์ด๋๋๋ค.
`๋น ๋ฅธ ํ์ด์ง ๋๋๋ง` ๋น ํ์ด์ง๊ฐ ์ ๋ฌ ๋์์ ๋, CSR ๋ฐฉ์์ ๋ธ๋ผ์ฐ์ ์์ ์ด์ฌํ ๋ด์ฉ์ ๊ทธ๋ฆฌ๋ ์์ ์ ํ ํ ๋ฐ, SSR ๋ฐฉ์์ ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ Server์์ ๊ทธ๋ฆฌ๋ ๊ฒ์ด์์. ๋ธ๋ผ์ฐ์ ๋ ์ด์ฉ์๊ฐ ์ฌ์ฉํ๋ ์ปดํจํฐ์์ ์์ ์ ํ๊ฒ ๋๋๋ฐ, ์ด์ฉ์๋ ์ ๊ฐํ ์ปดํจํฐ๋ฅผ ์ด์ฉํ๊ณ ์์์๋ ์๋ ๊ฒ์ด์์. ๊ทธ๋ ๋ค๋ฉด ๊ทธ ์ปดํจํฐ์์๋ CSR ๋ฐฉ์์์ ์ผ์ ํ๋๊ฒ ๋๋ฆด ์ ์์ ์ ์๋ ๊ฒ์ด์์. Server๋ ํฌ๊ณ , ๊ฐ์ฉ์ฑ์ด ๋์ ์ฅ๋น๋๊น Server์์ ๊ทธ๋ฆฌ๊ณ ์ค๋ฉด ๋ ๋น ๋ฅผ ์ ์๊ฒ ์ง์!
๋ํ, ์๋ฒ ์ฌ์ด๋ ๋ฐฉ์์ ๋น HTML Page๋ฅผ ๋ฐ์ ๋ธ๋ผ์ฐ์ ์์ ๊ทธ๋ฆฌ๋ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ฐฉ์๊ณผ ๋ค๋ฅด๊ฒ ์๋ฒ์์ ๋ฏธ๋ฆฌ ๊ทธ๋ ค ๋ธ๋ผ์ฐ์ ๋ก ๋ณด๋ด์ฃผ๊ธฐ ๋๋ฌธ์ ํ์ด์ง ๊ทธ๋ฆฌ๋ ์๊ฐ์ ๋จ์ถํ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ ๊ฒ์ด์์. ์ด์ฉ์ ์ ์ฅ์์๋ ํ๋ฉด์ ์ ์๋ฏธํ ์ ๋ณด๊ฐ ํ์๋๋ ์๊ฐ์ด ๋นจ๋ผ์ง๋ ๊ฒ์ด์์.
๐ฆ ๋จ์
๊ทธ๋ ๋ค๋ฉด ๋จ์ ์ ๋ฌด์์ด ์์๊น์? ์๋ฒ ์ฌ์ด๋ ๋ฐฉ์์ `Node.js`์ ๊ฐ์ Backend๋ฅผ ์์์ผ ํ๊ณ , ์๋ฒ์ชฝ ํ๊ฒฝ ๊ตฌ์ฑ๊ณผ ํจ๊ป ํด๋ผ์ด์ธํธ, ์๋ฒ ๋น๋์ ๋ํ ์ด์ ๊ฐ ํ์ํด์. ์ง์ ์ฅ๋ฒฝ์ด ์ข ๋๋ค๋ ๊ฒ ๋จ์ ์ผ ์ ์๊ฒ ์ง์.
๋ํ, `Node.js` ํ๊ฒฝ์์ ์คํ๋๊ธฐ ๋๋ฌธ์ ๋ธ๋ผ์ฐ์ ๊ด๋ จ API๋ฅผ ๋ค๋ฃฐ ๋ ์ฃผ์ํด์ผ ํ๋ ๊ฒ์ด์์. `Vue Single Page Application`์ Life Cycle Hook๊ณผ๋ ๋ค๋ฅธ ํ๊ฒฝ(๋ธ๋ผ์ฐ์ ๊ฐ ์๋ Node.js)์์ ๋์ํ๊ธฐ ๋๋ฌธ์ `beforeCreate`, `created`์์ `window`, `document`์ ๊ฐ์ ๋ธ๋ผ์ฐ์ ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์๋ต๋๋ค.
๐ก ์ฐธ๊ณ ์ฌํญ
Server Side Rendering์ ๊ฒฝ์ฐ Component๊ฐ ์ต์ด๋ก ์์ฑ๋๋ ์์ ์ด ๋ธ๋ผ์ฐ์ ์์ด ์๋๋ผ Node.js ํ๊ฒฝ์ด๊ธฐ ๋๋ฌธ์ beforeCreate๋ created์์ ๋ธ๋ผ์ฐ์ ๊ฐ์ฒด๋ฅผ ์ ๊ทผํ ์ ์๋ค. ๋์ beforeMount๋, mounted์์ window์ document๋ฅผ ์ ๊ทผํ ์ ์๋ค.
๐ฝ Client Side Rendering
๐ฆ ๊ฐ์
URL์ด ๋ณ๊ฒฝ์ด ๋๋ฉด Event(hashchange Event)๊ฐ ๋ฐ์ํ๊ฒ ๋๊ณ , ์ด๊ฒ์ด ๋ฐ๋ก Vue Router์ ๋ด๋ถ ๋์ ๋ฐฉ์ ์ฆ, ์ ์ฒด์ ์ธ SPA(Single Page Application)๋ ์ด๋ฐ Event๋ฅผ ํตํด ๋์ํ๊ณ ์์ต๋๋ค. ๊ฒฐ๊ตญ Event๋ฅผ ํตํด ํ๋ฉด์ ๋ฐ๊ฟ์ฃผ๋ ๊ฒ์ด SPA์ ํน์ง์ธ ๊ฒ์ด์์.
๐ฝ ๋์ ์ฐจ์ด์
๋จผ์ Client Side Rendering์ ์ดํดํ๊ธฐ ์ํด Vue Cli๋ก ์์ฑ๋ Project์ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ๊ฒ์ด์์.
์๋๋ Vue CLI๋ก ์์ฑํ Project ๊ธฐ๋ณธ Code์์.
// src/main.js
import Vue from "vue";
import App from "./App.vue";
new Vue({
render: (h) => h(App),
}).$mount("#app);
์ Code๋ Vue์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ Code์ธ๋ฐ, ์ด ๊ฐ์ฒด๋ ์๋ index.html ํ์ผ์ app ID๋ฅผ ๊ฐ๋ Tag์ ๋ถ์ฐฉ์ด ๋๊ฒ ๋๋ ๊ฒ์ด์์.
<!-- 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๋ก Project๋ฅผ ์์ฑํ ๋ค `npm run serve`๋ก ํ๋ก์ ํธ๋ฅผ ์คํํ๊ณ , ๋ธ๋ผ์ฐ์ ๋ฅผ ํ์ธํ๋ฉด Vue ๊ธฐ๋ณธ Page๊ฐ ๋ฐ ๊ฒ์ธ๋ฐ, ์ด ๋ ๊ฐ๋ฐ์ Panel์ `Network` Tab์์ `Doc`์ผ๋ก ํํฐ๋งํ ๊ฒฐ๊ณผ๋ฅผ ์๋์ ๊ฐ์ด ์ค๋นํด ๋ณด์์ด์.
์๋ฒ์์ ๋๊ฒจ๋ฐ์ HTML Code์๋ `body` Tag ๋ณธ๋ฌธ์ `<div id="app"></div>` ๋ฐ์ ์์ง๋ง, ํ๋ฉด์๋ `Welcome To Your Vue.js App` Text์ Image๊ฐ ์๋ ๊ฒ์ด์์. ์ด๊ฒ๋ค ๋ชจ๋ Client(๋ธ๋ผ์ฐ์ )์์ ๋์ํ `Vue.js`๊ฐ ๊ทธ๋ ค์ค ๊ฒ์ด๋๋๋ค. ์ฆ, ๋ธ๋ผ์ฐ์ ์์ ํ๋ฉด์ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋ ค๋ธ ๊ฒ์ด์์.
์๋ฒ ์ฌ์ด๋์ ํด๋ผ์ด์ธํธ ์ฌ์ด๋๋ ๋ฐ๋ก ์ด๋์ ํ๋ฉด์ ๋ณด์ผ ๋ด์ฉ์ ๊ทธ๋ฆฌ๋๋์ ์ฐจ์ด์ธ ๊ฒ์ด์์. ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ ๋๋ง์ ํ์ด์ง์ ๋ด์ฉ์ ๋ธ๋ผ์ฐ์ ์์ ๊ทธ๋ฆฌ๊ณ ์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์ ์๋ฒ์์ ํ์ด์ง์ ๋ด์ฉ์ ๋ค ๊ทธ๋ ค ๋ธ๋ผ์ฐ์ ์ ๋์ ธ์ฃผ๋ ๋ฐฉ์์ธ ๊ฒ์ด์์.
๐ฆ Client Side Rendering
๋จผ์ CSR ๋์ ๋ฐฉ์์ ์ดํดํ๊ธฐ ์ํด Vue.js๋ก ๋ง๋ค์ด์ง Google์ Careers Homepage๋ฅผ ์ดํด๋ณด๋ ค๊ณ ํด์.
๊ฐ๋ฐ์ ๋๊ตฌ(F12 Key)์์ `Network` Tab์ ๋ณด๋ฉด ์๋์ ๊ฐ์ด Filter๊ฐ ์ฌ๋ฌ๊ฐ ์๋ ๊ฒ์ ๋ณผ ์ ์์ด์.
์ผ๋จ ์ง๊ธ์ `All` Filter (์๋ฌด Filter๋ฅผ ๊ฑธ์ง ์๋๋ค.) ์ํ์ธ๋ฐ, ์ฌ๊ธฐ์ `Doc(Document)` Tab์ ์ ํํด์ Server์์ ๋ฐ์์จ Data๋ฅผ ํ์ธํด ๋ณผ ๊ฒ์ด์์.
์ฌ๊ธฐ์ ๋งจ ์์ careers.google.com Document์ Response(์๋ต)์ ์ ํํด์ ํ์ธ ํด ๋ณด๋ฉด
์ด๋ ๊ฒ ์๋ต์ด ์จ ๊ฒ์ ํ์ธํ ์ ์๋๋ฐ, ์์ 93๋ฒ์งธ ์ค `<div id="app-root"></div>`๋ฅผ ๋ณด๋ฉด div Tag์์ ์ด๋ค ๋ด์ฉ๋ ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ ๊ฒ์ด์์.
๊ทธ๋ฐ๋ฐ, ๊ฐ๋ฐ์ ๋๊ตฌ ์์๋ฅผ ํตํด ํ์ธํด ๋ณด๋ฉด ์ ๋ง ์ด๋ง์ด๋งํ๊ฒ ๋ง์ Tag๋ค์ด ์๋ ๊ฒ์ ๋ณผ ์ ์๋ ๊ฒ์ด์์.
๊ทธ๋์ผ์ง ํ๋ฉด์ด ๋์ฌํ ๋๊น์!
์ฆ, ์์์ ๋ณธ ๊ฒ๊ณผ ๊ฐ์ด SPA(Single Page Application)๋, CSR(Client Side Rendering) ๋ฐฉ์์ ๋ธ๋ผ์ฐ์ ์์ html์ ๋ฐ์์์ ๋, `<div id="app-root"></div>`์์ ์๋ ๋ชจ๋ ๋ด์ฉ์ ๋ธ๋ผ์ฐ์ ์์ ๊ทธ๋ฆฌ๋ ๋ฐฉ์์ ๋๋ค.
๐ฆ Server Side Rendering
์ด๋ฒ์๋ ์บกํดํ๊ต๋์ Blog๋ฅผ ํ๋ฒ ๊ฐ๋ฐ์ ๋๊ตฌ๋ก ํ์ธํด ๋ณผ๊ฒ์.
์์ CSR๊ณผ์ ์ฐจ์ด์ ์ ๊ฐ๋ฐ์ ๋๊ตฌ์์ ๋ณด๋ฉด CSR๊ณผ ๋ค๋ฅด๊ฒ ๋ชจ๋ Text, html Tag ๋ฑ์ ๋ด์ฉ์ด ์ถ๋ ฅ๋๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค.
๐ฝ Nuxt.js๋ฅผ ์ฌ์ฉํ๋ฉด ์ข์์
Nuxt.js๋ก ๊ฐ๋ฐํ๋ฉด ์๋์ ๊ฐ์ ์ฅ์ ์ด ์์ต๋๋ค.
โ ๊ฒ์ ์์ง ์ต์ ํ
โ ์ด๊ธฐ ํ๋ก์ ํธ ์ค์ ๋น์ฉ ๊ฐ์์ ์์ฐ์ฑ ํฅ์
โฆ ESLint, Pretter.
โฆ ๋ผ์ฐํฐ, ์คํ ์ด ๋ฑ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น ๋ฐ ์ค์ ์ ํ ํ์ ์์.
โฆ ํ์ผ ๊ธฐ๋ฐ์ ๋ผ์ฐํ
๋ฐฉ์์ผ๋ก ์ค์ ํ์ผ ์๋ ์์ฑ.
โ ํ์ด์ง ๋ก๋ฉ ์๋์ ์ด์ฉ์ ๊ฒฝํ ํฅ์
โฆ ๋ธ๋ผ์ฐ์ ๊ฐ ํ๋ ์ผ์ ์๋ฒ์ ๋๋ ์ ์๋ค.
โฆ ๋ชจ๋ฅด๋ฉด ์ง๋์น ์ ์๋ ์ฝ๋ ์คํ๋ฆฌํ
๊ธฐ๋ณธ ์ค์ .
์ฐธ๊ณ ์๋ฃ : Nuxt.js ์์ํ๊ธฐ - ์ธํ๋ฐ
'Front-End ์์ ์ค > Nuxt.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Vue+Nuxt.js] Nuxt.js๋ฅผ ์ด์ฉํ์ฌ ์ผํ ์ํ ๊ฒ์ UI ๊ฐ๋ฐ (0) | 2022.06.01 |
---|---|
[Vue+Nuxt.js] Nuxt.js๋ฅผ ์ด์ฉํ์ฌ ์ผํ ์ํ ๋ชฉ๋ก ํ์ด์ง์ ์์ธ ํ์ด์ง ๊ฐ๋ฐ (0) | 2022.05.24 |
[Vue+Nuxt.js] Nuxt.js Data ํธ์ถ ๋ฐฉ์๊ณผ API ์ฐ๋ (0) | 2022.05.22 |
[Nuxt.js] ๋น๋๊ธฐ ๋ฐ์ดํฐ ํธ์ถ ๋ฐฉ๋ฒ (0) | 2022.05.22 |
[Vue+Nuxt.js] Nuxt.js ์์ํ๊ธฐ (0) | 2022.05.18 |