brunch

You can make anything
by writing

C.S.Lewis

by 에디의 기술블로그 Apr 10. 2018

[프론트엔드]Vue.js 스터디(3일차)

- Vue.js , Spring 환경으로 간단한 웹사이트 구축하기

Vue.js, Spring Boot Getting Started

Spring Boot 환경에서 Vue.js 기반의 심플한 웹사이트를 구축한다.

by. 나



Overview 

관련 연구

기본 환경 구축

Vue SPA 심화

정리



Overview

기술 스펙

Vue.js

Webpack

Spring Boot 2.0

Gradle

intellij

요구사항

간단한 웹사이트를 만든다.

SPA 개념을 도입한다.

Spring Boot 환경에서 띄운다. 즉, Jar 로 빌드할 수 있어야 한다. 


관련 연구

관련 기술에 대해서 간략하게 정리한다. 


SPA(Single Page Application)

SPA(단일 페이지 애플리케이션)는 모던한 웹 개발 방법으로, 기본적으로 단일 페이지로 구성되며 네이티브 앱과 유사한 사용자 경험을 제공한다고 한다. 단일 페이지 애플리케이션은 CSS, Javascript 번들 리소스를 포함하는 심플한 HTML의 화면으로 구성되며, 사용자의 요청에 의해서 새로운 페이지를 호출하지 않고 현재 페이지에서 동적으로 빠르게 사용자에게 화면을 재구성한다.

A single-page application (SPA) is a web application or web site that interacts with the user by dynamically rewriting the current page rather than loading entire new pages from a server.

기존에 개발 방법과는 많이 다르기 때문에 사실 나는 아직도 이 방법이 익숙하지는 않다. SPA가 무조건 좋은 것은 아니다. 장단점이 있다. 자세한 내용은 아래 링크를 참고하자. 

https://medium.com/@NeotericEU/single-page-application-vs-multiple-page-application-2591588efe58


Vue.js

Vue.js에 대해서는 공식 가이드를 참고하자.

https://kr.vuejs.org/v2/guide/index.html


Backend for Front-End Pattern

https://docs.microsoft.com/ko-kr/azure/architecture/patterns/backends-for-frontendshttps://samnewman.io/patterns/architectural/bff/


Webpack

생략...



기본 환경 구축

Spring Boot, Gradle 디펜던시

Gradle 기반으로 스프링 부트 웹 프로젝트를 시작한다. 디펜던시는 아래와 같이 추가하였다.

dependencies {
   compile('org.springframework.boot:spring-boot-starter-freemarker')
   compile('org.springframework.boot:spring-boot-starter-web')
   compile 'org.projectlombok:lombok:1.16.16'
   testCompile('org.springframework.boot:spring-boot-starter-test')
}


Vue.js , jQuery, BootStrap

필요한 모듈을 설치해야 한다. 아래와 같이 터미널에서 필요한 모듈을 설치한다.

npm install -save jquery
npm install -save vue
등등.. 필요한 거 알아서 잘 설치하면 된다.

node_modules 디렉토리에 해당 모듈이 생성이 된다. 그리고 package.json 파일에 추가가 된다. 더 간단한 방법은 누군가가 만든 package.json 을 가져온 다음에 npm install 만 하면 전부 설치 추가된다.

npm install

package.json 파일을 수정하고 npm install을 실행하면 변경된 모듈이 재적용된다. 예를 들어서, 내가 jquery 버전을 1.X 로 적용하고 싶다면, 아래와 같이 변경하고 npm install을 하면 새로 적용된다.

"jquery.1": "^1.0.0",


프로젝트 디렉토리 구조

사용자가 보는 화면의 모든 기능은 프론트엔드단 수행한다. 저기 하나 있는 index.ftl 은 그냥 껍데기 페이지이다. 백엔드에서는 비즈니스 로직 및 데이터를 API 형태로 구현한다. 즉, Backend for Front-End Pattern 을 적용한다. main\java 하위에 클래스는 백엔드에서 처리하는 로직을 포함한다. 그 외에 프론트엔드 기능은 main\js 밑에 vue 파일과 js 파일에 구현한다.


node_modules : npm 으로 설치된 모듈 파일

out/production: 실제로 요청에 의해서, 애플리케이션에서 실행되는 파일

src/main/java

src/main/resources

src/main/js : Vue, js, css 파일 등 프론트엔드 관련 파일이 포함된다. 


그리고 Spring MVC 구조의 특성을 고려하여, 프론트엔드에서 생성하는 bundle.js 파일을 out/production 디렉토리로 복사해야 한다. CSS 파일 역시 마찬가지이다. webpack.config.js 파일을 아래와 같이 수정한다. 

//webpack.config.js 파일 설정
//브런치에 작성한 코드는 들여 쓰기가 엉망이다...


생략...
output: {       
    filename: 'js/bundle.js',     
    path: __dirname + '/build/resources/main/static'   
},
생략...

plugins: [       
    new ExtractTextPlugin("css/styles.css"),     
    new FileManagerPlugin({           
        onEnd: {               
            copy: [                   
                {                       
                    source: __dirname + '/build/resources/main/static/js/bundle.js',
                    destination: __dirname + '/out/production/resources/static/js/bundle.js'                 },     
                {                       
                    source: __dirname + '/build/resources/main/static/css/styles.css',                     destination: __dirname + '/out/production/resources/static/css/styles.css'                 }               
               ]           
        }       
})   
]

암튼 디렉토리 구조가 익숙하지는 않다. 일반적으로 Spring MVC 개발을 하면 Javascript 파일은 resource/static 밑에 포함하지만, 해당 프로젝트에서는 새로 만든 디렉토리에 js 파일을 구성한다. 핵심 파일을 아래와 같이 정리하였다.


app.js : Webpack 엔트리 페이지, 초기 호출 파일이라고 생각하면 된다.

App.vue : app.js 파일에서 설정하는 루트 컴포넌트 페이지

route.js : Vue 컴포넌트의 페이지 라우팅 설정

pages/페이지.vue : 각종 Vue 컴포넌트 페이지


웹브라우저가 처음 렌더링 하는 화면

아래 소스가 끝이다. 나는 이 소스를 보고 깨달았다. 아 이게 SPA 이구나...

어쨌든 Vue 컴포넌트 파일은 모두 bundle.js 하나의 파일에 빌드된다. 


최종 Webpack.config

https://github.com/sieunkr/vuejs-sample/blob/master/quiz-web-v1/webpack.config.js

상세한 설명은 생략한다. 왜냐면 내가 자세히 모른다. 그리고 웹팩이 너무 어렵다.


npm run dev

매우 중요한 내용이다. webpack을 사용 중인 개발자는 다 아는 내용일 것이다. 개발 중에도 바로바로 js 가 빌드되어서, 개발이 편리하도록 설정해야 한다. 


"scripts": {     "build": "webpack",   "dev": "webpack -w" ... 생략..

intellij 의 터미널에서 npm run dev을 실행하면, 변경된 파일이 자동으로 vue-loader 에 의해서 빌드가 될 것이고, bundle.js 파일이 생성될 것이다. 기초적인 내용이지만 매우 중요하다. 소스를 수정하면 아래와 같이 빌드되는 것을 확인할 수 있다.


자!! 이제 Intellij에서 Vuejs 파일을 수정하면서 굳이 서버를 재시작할 필요가 없다


Gradle npm 빌드 추가

필자는 해당 프로젝트를 스프링 부트 jar 파일로 만들고, 리눅스 서버에 배포할 것이다. 그러기 위해서는 서버 빌드 시에도, npm 빌드가 함께 수행이 되어야 한다. 아래 파일 참고만 하자.


buildscript {  

   ext {  

      springBootVersion = '2.0.0.RELEASE'  

  }  

   repositories {  

      maven {  

         url "https://plugins.gradle.org/m2/"  

  }  

   }  

   dependencies {  

      classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")  

      classpath "com.moowork.gradle:gradle-node-plugin:1.2.0"  

  }  

}    

apply plugin: 'java'  

apply plugin: 'eclipse'  

apply plugin: 'org.springframework.boot'  

apply plugin: 'io.spring.dependency-management'  

apply plugin: "com.moowork.node"    

group = 'quiz'  

version = '0.0.1-SNAPSHOT'  

sourceCompatibility = 1.8      

node {  

   version = '9.8.0'  

  npmVersion = '5.6.0'  

  download = true  

}    

repositories {  

   maven { url "http://repo.maven.apache.org/maven2" }  

}      

dependencies {  

   compile('org.springframework.boot:spring-boot-starter-freemarker')  

   compile('org.springframework.boot:spring-boot-starter-web')  

   compile 'org.projectlombok:lombok:1.16.16'  

  testCompile('org.springframework.boot:spring-boot-starter-test')  

}    

task webpack(type: NodeTask, dependsOn: 'npmInstall') {  

   def osName = System.getProperty("os.name").toLowerCase();  

   if (osName.contains("windows")) {  

      script = project.file('node_modules/webpack/bin/webpack.js')  

   } else {  

      script = project.file('node_modules/.bin/webpack')  

   }  

}    

processResources.dependsOn 'webpack'    

clean.delete << file('node_modules')


하지만, 굳이 이렇게 할 필요는 없다. 그냥 Node 서버를 구축해라. 그리고, 해당 서버에서는 git으로 Vue 등 필요한 파일을 Pull 해서 빌드해서 서비스하면 된다. 참고로, 위에도 말했지만, 내가 이렇게 구현한 이유는 스프링 환경에서 서비스를 운영하고 싶기 때문이다. 프런트엔드에서는 각종 UI 기능을 담당하고, 백단에서는 스프링 환경의 비즈니스 로직을 수행하기 위해서이다.


추가 의견 1

확장자를 vue로 하면 처음에는 오류가 표시될 것이다. 인텔리 J 에서 아래와 같이 Vue 플러그인을 설치하면 해결된다.

의견 2

또한, ES6 문법 오류가 발생한다면, intellij 에서 자바스크립트 설정을 바꾸면 오류가 나지 않는다. 금방 찾는다.

의견 3

같은 얘기가 반복되지만, 굳이 Spring 부트로 안 해도 된다. 그냥 Node 서버로 올려도 된다. 나는 Spring을 고집한다. 왠지 모르겠지만 그렇다. 


배포

배포는 그냥 일반적인 jar 배포와 똑같다. 실제 배포 스크립트는 좀 더 복잡하겠지만, 쉽게 설명하면...


java -jar xxxxx.jar 


끝이다.  참고로 아까 gradle 에서 설정에 의해서 빌드시에 알아서 Vue 파일등을 패키징 해준다. 


Vue SPA 심화

Vue 파일 구조

Vue 컴포넌트는 기본적으로 아래와 같은 구조로 구성된다. 

<template>
    <div>
    </div>
</template>


<script>
export default {
    data() {
            return {
            }
      },
    mounted() {
        },
    methods:  {
        };
</script>
<style>
</style>

template 에는 id 를 설정하지 않는다. 그리고 반드시 div 태그가 있어야 한다. 해당 컴포넌트 파일의 시작점은 바로 webpack 에서 엔트리로 지정된 파일에서 시작한다. 필자는 엔트리 파일로 /src/main/js/app.js 를 지정하였고, 해당 파일에는 아래와 같이 작성하였다.


생략...
new Vue({           
        router,     
    render: h => h(App)   
}).$mount('#app');


만들어서 배포한 화면은 아래 링크를 확인하자. 나름 재미나다.

http://vuejs.co.kr/#/


소스는 아래 허접한 github에서 확인하길 바란다. 

https://github.com/sieunkr/vuejs-sample/tree/master/quiz-web-v1


이제 봐야 할 것은 아래와 같다. 

컴포넌트 추가 방법

data() 설정

methods

Axios 를 활용한 ajax 통신

vue 라우팅 설정

vuex 를 활용한 데이터 공유


등등. 중요한 내용이 많지만, 오늘은 여기까지만 작성하고 마무리하겠다;;;;  뭔가 정말 중요한 내용 시작인데.... 퇴근 후 지친 상태라서 더이상 글을 자세히 쓸수가 없다. 다음 시간에는 더 자세히 작성하기를 희망한다. 


왠지 또 작심삼일 이겠지만ㅠㅠ


오해 없기를 바라며...

1. 필자는 프론트엔드 무식자이다. 해당 글에서 틀린 내용이 있을 수 있다. 

2. 외부 사례를 확인해보니 대부분 vue-cli 를 사용하는 것으로 확인 되었다. 나는 뭔가 자동으로 구성해주는게 조심스러워서 사용은 하지 않았다. 주변에서 얘기를 들으니 꽤 편하다고 한다. 

3. Vue파일이 포함된 디렉토리를 js 라고 명명했다. 다른 외부 사례를 보니 frontend 라고 명명한 경우도 있다. 큰 의미는 없다. 알아서 잘하면 된다. 

4. 구축한 웹팩 환경이, 테스트 환경이 구축되지 않았다. 필자는 자바스크립트의 테스트 환경 구축에 대해서 잘 모르는 상황이다. 필자처럼 하지 말고, 테스트 환경이 가능하도록 구현하길 바란다. 


혹시라도 이 글을 보시는 분중에서, Spring Boot + Vue.js 구축하신 분 계시면 조언 부탁드립니다. ㅠㅠ 


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari