{"componentChunkName":"component---src-templates-blog-post-js","path":"/vue/vue-js-서버-사이드-렌더링/","result":{"data":{"site":{"siteMetadata":{"title":"Bottlehs Tech Blog","description":"웹·앱·AI 개발자 전병훈(bottlehs)의 기술 블로그. AI·LLM, JavaScript·Vue, Spring Boot, 알고리즘, 블록체인 실무 가이드를 다룹니다","siteUrl":"https://www.bottlehs.dev","author":{"name":"Jeon Byung Hun","summary":"개발을 즐기는 bottlehs - Engineer, MS, AI, FE, BE, OS, IOT, Blockchain, 설계, 테스트"},"social":{"github":"bottlehs","codepen":"bottlehs"}}},"markdownRemark":{"id":"7db8cc42-cc09-5093-bbb3-878f65ec03e9","excerpt":"Vue Js 서버 사이드 렌더링 서버 사이드 렌더링이란 서버에서 페이지를 렌더링후 클라이언트(브라우저)로 보내 화면에 표시하는 기법을 의미한다. 뷰 싱글 페이지 애플리케이션을 서버 사이드 렌더링의 반대인 클라이언트 사이드 렌더링 방식이다. CSR, SSR 차이점 CSR HTML, JS…","html":"<p><img src=\"/assets/vue-logo.png\" alt=\"Vue Js 서버 사이드 렌더링\" title=\"Vue Js 서버 사이드 렌더링\"></p>\n<p>서버 사이드 렌더링이란 서버에서 페이지를 렌더링후 클라이언트(브라우저)로 보내 화면에 표시하는 기법을 의미한다. 뷰 싱글 페이지 애플리케이션을 서버 사이드 렌더링의 반대인 클라이언트 사이드 렌더링 방식이다.</p>\n<h2 id=\"csr-ssr-차이점\" style=\"position:relative;\"><a href=\"#csr-ssr-%EC%B0%A8%EC%9D%B4%EC%A0%90\" aria-label=\"csr ssr 차이점 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>CSR, SSR 차이점</h2>\n<h3 id=\"csr\" style=\"position:relative;\"><a href=\"#csr\" aria-label=\"csr permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>CSR</h3>\n<p>HTML, JS, CSS 만 서버에서 받고 사용자에게 보여줄 데이터를 포함한 UI는 클라이언트에서 랜더링후 화면에 표시 한다.</p>\n<h3 id=\"ssr\" style=\"position:relative;\"><a href=\"#ssr\" aria-label=\"ssr permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>SSR</h3>\n<p>HTML, JS, CSS 및 화면에 표시해줄 데이터를 포함한 UI를 서버에서 랜더링하여 클라이언트 화면에 표시 한다.</p>\n<p><img src=\"/assets/vue-ssr-vs-csr2.png\" alt=\"Vue Js CSR, SSR\" title=\"Vue Js CSR, SSR\"></p>\n<p>위 예시를 보면 SSR 의 경우 Main 이 소스코드 보기에서 보이고, CSR 의 경우 Main 이 소스코드 보기에서 보이지 않는다.\n이유는 SSR는 서버에서 렌더링 되었기 때문에 Main 이 보이는것이고 CSR 은 브라우저에서 아직 랜더링이 되지 않았기 때문에 Main 이 보이지 않는 것이다.</p>\n<p><img src=\"/assets/vue-ssr-vs-csr.png\" alt=\"Vue Js CSR, SSR\" title=\"Vue Js CSR, SSR\"></p>\n<h2 id=\"서버-사이드-렌더링-사용-목적\" style=\"position:relative;\"><a href=\"#%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81-%EC%82%AC%EC%9A%A9-%EB%AA%A9%EC%A0%81\" aria-label=\"서버 사이드 렌더링 사용 목적 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>서버 사이드 렌더링 사용 목적</h2>\n<p>서버 사이드 렌더링을 쓰는 목적은 크게 “검색 엔진 최적화”와 “빠른 페이지 렌더링”이다. 검색 엔진 최적화란 구글, 네이버, 다음과 같은 검색 사이트에서 검색했을 때 결과가 사용자에게 많이 노출될 수 있도록 최적화 하는 기법이다. 특히, SNS에서 링크를 공유했을 때 해당 웹 사이트의 정보를 이미지와 설명으로 표시해주는 OG(Open Graph) Tag를 페이지 별로 적용하기 위해서는 서버 사이드 렌더링이 효율적이다.</p>\n<p><img src=\"/assets/og-tags-1.png\" alt=\"Vue Js Facebook OG Tags 1\" title=\"Vue Js Facebook OG Tags 1\"></p>\n<p><img src=\"/assets/og-tags-2.png\" alt=\"Vue Js Facebook OG Tags 2\" title=\"Vue Js Facebook OG Tags 2\"></p>\n<h2 id=\"서버-사이드-렌더링-단점\" style=\"position:relative;\"><a href=\"#%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81-%EB%8B%A8%EC%A0%90\" aria-label=\"서버 사이드 렌더링 단점 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>서버 사이드 렌더링 단점</h2>\n<p>서비사이드 렌더링 사용 목적을 보면 서버 사이드 렌더링이 좋다고 생각 될것이다. 하지만 서버 사이드 렌더링을 하기전에 주의해야 할 점이 있다. 서버 사이드 렌더링은 Node.js 웹 애플리케이션 실행 방법을 알아야하고 서버쪽 환경 구성과 함께 클라이언트, 서버 빌드에 대한 이해가 필요하다. 따라서, 프론트엔드 개발 입문자 입장에서는 진입이 어렵다 그리고 Node.js 환경에서 실행되기 때문에 브라우저 관련 API를 다룰 때 주의해야 한다. 뷰 싱글 페이지 애플리케이션의 라이프 사이클 훅과는 다른 환경(브라우저가 아닌 Node.js)에서 동작하기 때문에 beforeCreate와 created에서 window나 document와 같은 브라우저 객체에 접근할 수 없다. ( beforeMount나 mounted에서 window와 document를 접근할 수 있다 )</p>\n<h2 id=\"nuxtjs-특징-및-활용\" style=\"position:relative;\"><a href=\"#nuxtjs-%ED%8A%B9%EC%A7%95-%EB%B0%8F-%ED%99%9C%EC%9A%A9\" aria-label=\"nuxtjs 특징 및 활용 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Nuxt.js 특징 및 활용</h2>\n<h3 id=\"nuxt-란\" style=\"position:relative;\"><a href=\"#nuxt-%EB%9E%80\" aria-label=\"nuxt 란 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Nuxt 란</h3>\n<p>Nuxt.js는 Vue.js 응용 프로그램을 만들기 위한 Framework이며, Vue.js Application을 좀 더 손쉽게 만들 수 있으며 Server-Side-Rendering을 지원한다.</p>\n<h3 id=\"nuxt-특징\" style=\"position:relative;\"><a href=\"#nuxt-%ED%8A%B9%EC%A7%95\" aria-label=\"nuxt 특징 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Nuxt 특징</h3>\n<ul>\n<li>서버 사이드 렌더링</li>\n<li>규격화된 폴더 구조(layout, store, middleware, plugins 등)</li>\n<li>pages 폴더 기반의 자동 라우팅 설정</li>\n<li>코드 스플리팅</li>\n<li>비동기 데이터 요청 속성</li>\n<li>ES6/ES6+ 변환</li>\n<li>웹팩을 비롯한 기타 설정</li>\n</ul>\n<h3 id=\"활용\" style=\"position:relative;\"><a href=\"#%ED%99%9C%EC%9A%A9\" aria-label=\"활용 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>활용</h3>\n<p>npm 을 통한 프로젝틑 셋팅</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm init nuxt-app@latest &lt;my-project></code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">cd my-project\nnpm run dev</code></pre></div>\n<p><img src=\"/assets/nuxt-run-dev-1.png\" alt=\"Nuxt Run dev\" title=\"Nuxt Run dev\"></p>\n<p><img src=\"/assets/nuxt-run-dev-2.png\" alt=\"Nuxt Run dev\" title=\"Nuxt Run dev\"></p>\n<p><code class=\"language-text\">npm run dev</code> 실행 하면 서버에서 렌더링 과정을 거치게 되고, 렌더링후 서버가 실행 되면 브라우저에서 확인할수 있다.</p>\n<p><img src=\"/assets/nuxt-index.png\" alt=\"Nuxt Run dev\" title=\"Nuxt Run dev\"></p>\n<p>외부 API 를 활용하여 서버에서 API 를 요청하고 요청한 결과를 렌더링된 HTML 에 포함시키는 간단한 코드를 작성해 보자</p>\n<p>nuxt/axios 를 설치 한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm install @nuxtjs/axios</code></pre></div>\n<p>nuxt.config.js 에 axios module 설정을 해준다.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">export default {\n  modules: [\n    '@nuxtjs/axios',\n  ],\n  axios: {\n    baseURL: 'https://testrestapi.cafe24.com',\n  },\n}</code></pre></div>\n<p>pages/index.vue 에 axios 를 활용하여 sample api 를 요청 하는 코드를 작성 한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"html\"><pre class=\"language-html\"><code class=\"language-html\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>template</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>div</span><span class=\"token punctuation\">></span></span>{{ sample }}<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>div</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>template</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">async</span> <span class=\"token function\">asyncData</span><span class=\"token punctuation\">(</span><span class=\"token parameter\"><span class=\"token punctuation\">{</span> $axios <span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> sample <span class=\"token operator\">=</span> <span class=\"token keyword\">await</span> $axios<span class=\"token punctuation\">.</span><span class=\"token function\">$get</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">/api/sample/sample</span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span> sample <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>실행 결과 화면은 아래와 같다.</p>\n<p><img src=\"/assets/nuxt-index-2.png\" alt=\"Nuxt Axios\" title=\"Nuxt Axios\"></p>\n<h2 id=\"vue-server-renderer-활용\" style=\"position:relative;\"><a href=\"#vue-server-renderer-%ED%99%9C%EC%9A%A9\" aria-label=\"vue server renderer 활용 permalink\" class=\"anchor-header before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Vue Server Renderer 활용</h2>\n<p>npm 을 통한 초기화</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm init</code></pre></div>\n<p>name 은 <code class=\"language-text\">vue-ssr</code> 로 입력 하자. 아래는 npm 으로 초기화한 package.json 이다.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">{\n  \"name\": \"vue-ssr\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" &amp;&amp; exit 1\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\"\n}</code></pre></div>\n<p><code class=\"language-text\">vue</code>,<code class=\"language-text\">vue-server-renderer</code> 를 설치 한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm install vue vue-server-renderer --save</code></pre></div>\n<p>package.js 에서 설치된 vue, vue-server-renderer 를 확인 한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">\"dependencies\": {\n  \"vue\": \"^2.6.12\",\n  \"vue-server-renderer\": \"^2.6.12\"\n}</code></pre></div>\n<p>server.js 파일 생성후 vue 를 서버에서 랜더링 해보도록 하겠다.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token comment\">// server.js</span>\n\n<span class=\"token comment\">// Vue 인스턴스 생성</span>\n<span class=\"token keyword\">const</span> Vue <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"vue\"</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> app <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Vue</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n  <span class=\"token literal-property property\">template</span><span class=\"token operator\">:</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">&lt;div>Hello World&lt;/div></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\">// 렌더링</span>\n<span class=\"token keyword\">const</span> renderer <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"vue-server-renderer\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">createRenderer</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\">// Vue 인스턴스를 HTML로 렌더링</span>\nrenderer<span class=\"token punctuation\">.</span><span class=\"token function\">renderToString</span><span class=\"token punctuation\">(</span>app<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">err<span class=\"token punctuation\">,</span> html</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span> <span class=\"token keyword\">throw</span> err\n  console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>html<span class=\"token punctuation\">)</span>\n  <span class=\"token comment\">// => &lt;div data-server-rendered=\"true\">Hello World&lt;/div></span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\nrenderer\n  <span class=\"token punctuation\">.</span><span class=\"token function\">renderToString</span><span class=\"token punctuation\">(</span>app<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">html</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span>html<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">catch</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">err</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    console<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>위와 같이 server.js 파일 생성후 코드를 작성한뒤 아래와 같이 터미널에 입력 해보도록 하자</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">node server.js</code></pre></div>\n<p><img src=\"/assets/vue-ssr-server-1.png\" alt=\"server.js 실행 화면\" title=\"server.js 실행 화면\"></p>\n<p>Vue 인스턴스 생성후 HTML 랜더링된 HTML 코드가 콘솔로 찍히는걸 확인 할수 있다.\n여기서 node 는 node 로 server.js 파일을 실행해라 하는 의미 이다.</p>\n<p>이제 서버사이드에서 Vue가 랜더링되는걸 확인 했으니 Express.js 를 설치하여 Express.js 프레임워크에서 Vue 가 랜더링 되도록 해볼것 이다.</p>\n<p>Express.js 는 웹 애플리케이션, API 개발을 위해 설계되었고. Node.js의 표준 서버 프레임워크 라고 할수 있다.</p>\n<p>아래와 같이 npm 을 사용해서 Express.js 를 설치 한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">npm install express --save</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">{\n  \"name\": \"vue-ssr\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" &amp;&amp; exit 1\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"express\": \"^4.17.1\",\n    \"vue\": \"^2.6.12\",\n    \"vue-server-renderer\": \"^2.6.12\"\n  }\n}</code></pre></div>\n<p>설치가 완료 되었으면 Express.js 를 실행해 보도록 하자</p>\n<p>아래와 같이 server.js 에 아래와 같은 코드를 입력 한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token keyword\">const</span> Vue <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"vue\"</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> server <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"express\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">const</span> renderer <span class=\"token operator\">=</span> <span class=\"token function\">require</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"vue-server-renderer\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">createRenderer</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\nserver<span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"*\"</span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">req<span class=\"token punctuation\">,</span> res</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> app <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Vue</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>\n    <span class=\"token literal-property property\">data</span><span class=\"token operator\">:</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token literal-property property\">url</span><span class=\"token operator\">:</span> req<span class=\"token punctuation\">.</span>url<span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n    <span class=\"token literal-property property\">template</span><span class=\"token operator\">:</span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">&lt;div>The visited URL is: {{ url }}&lt;/div></span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n  renderer<span class=\"token punctuation\">.</span><span class=\"token function\">renderToString</span><span class=\"token punctuation\">(</span>app<span class=\"token punctuation\">,</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">err<span class=\"token punctuation\">,</span> html</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>err<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      res<span class=\"token punctuation\">.</span><span class=\"token function\">status</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">end</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Internal Server Error\"</span><span class=\"token punctuation\">)</span>\n      <span class=\"token keyword\">return</span>\n    <span class=\"token punctuation\">}</span>\n    res<span class=\"token punctuation\">.</span><span class=\"token function\">end</span><span class=\"token punctuation\">(</span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`</span><span class=\"token string\">\n      &lt;!DOCTYPE html>\n      &lt;html lang=\"en\">\n        &lt;head>&lt;title>Hello&lt;/title>&lt;/head>\n        &lt;body></span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span>html<span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">&lt;/body>\n      &lt;/html>\n    </span><span class=\"token template-punctuation string\">`</span></span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\nserver<span class=\"token punctuation\">.</span><span class=\"token function\">listen</span><span class=\"token punctuation\">(</span><span class=\"token number\">8080</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>Express.js 를 실행해 보자 <code class=\"language-text\">server.listen(8080)</code> 은 8080 포트로 node 서버를 실행하겠다는 의미 이다.</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">node server.js</code></pre></div>\n<p><img src=\"/assets/vue-ssr-express-1.png\" alt=\"server.js 실행 화면 - Express\" title=\"server.js 실행 화면 - Express\"></p>","tableOfContents":"<ul>\n<li>\n<p><a href=\"/vue/vue-js-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81/#csr-ssr-%EC%B0%A8%EC%9D%B4%EC%A0%90\">CSR, SSR 차이점</a></p>\n<ul>\n<li><a href=\"/vue/vue-js-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81/#csr\">CSR</a></li>\n<li><a href=\"/vue/vue-js-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81/#ssr\">SSR</a></li>\n</ul>\n</li>\n<li><a href=\"/vue/vue-js-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81/#%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81-%EC%82%AC%EC%9A%A9-%EB%AA%A9%EC%A0%81\">서버 사이드 렌더링 사용 목적</a></li>\n<li><a href=\"/vue/vue-js-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81/#%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81-%EB%8B%A8%EC%A0%90\">서버 사이드 렌더링 단점</a></li>\n<li>\n<p><a href=\"/vue/vue-js-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81/#nuxtjs-%ED%8A%B9%EC%A7%95-%EB%B0%8F-%ED%99%9C%EC%9A%A9\">Nuxt.js 특징 및 활용</a></p>\n<ul>\n<li><a href=\"/vue/vue-js-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81/#nuxt-%EB%9E%80\">Nuxt 란</a></li>\n<li><a href=\"/vue/vue-js-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81/#nuxt-%ED%8A%B9%EC%A7%95\">Nuxt 특징</a></li>\n<li><a href=\"/vue/vue-js-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81/#%ED%99%9C%EC%9A%A9\">활용</a></li>\n</ul>\n</li>\n<li><a href=\"/vue/vue-js-%EC%84%9C%EB%B2%84-%EC%82%AC%EC%9D%B4%EB%93%9C-%EB%A0%8C%EB%8D%94%EB%A7%81/#vue-server-renderer-%ED%99%9C%EC%9A%A9\">Vue Server Renderer 활용</a></li>\n</ul>","wordCount":{"words":572},"fields":{"slug":"/vue/vue-js-서버-사이드-렌더링/","image":"/assets/vue-logo.png","faq":[]},"frontmatter":{"title":"Vue Js 서버 사이드 렌더링","date":"2021년 5월 16일","dateISO":"2021-05-16T16:11:34.709Z","updatedISO":null,"category":"vue","description":null,"tags":["vue","javascript","framework","frontend","web","ssr"]}}},"pageContext":{"slug":"/vue/vue-js-서버-사이드-렌더링/","previous":{"fields":{"slug":"/vue/vue-js-jwt-기반-사용자-인증/"},"frontmatter":{"title":"Vue Js 뷰 JWT 기반 사용자 인증","tags":["vue","javascript","framework","frontend","web","router guards","jwt"]}},"next":{"fields":{"slug":"/vue/vue-js-한글-입력/"},"frontmatter":{"title":"Vue Js 한글 입력 과 IME","tags":["vue","javascript","framework","frontend","web","ime"]}}}},"staticQueryHashes":["213619243","3262363727"]}