본문 바로가기

스터디/스프링

SpringBoot + Vue 하나의 포트로 개발해보기

Spring과 Vue js를 개발할 때 일반적으로 서로 다른 포트를 띄워 개발하고, 배포시에는 같이 빌드시켜 하나의jar로말아서 배포한다.
그러다 보니 개발환경(백엔드와 프론트가 각각의 포트를 갖는 환경)과 운영환경(하나의 웹서버)이 달라 개발환경에서는 몰랐던 문제들이 발생할 수 있다.
웹팩의 장점을 가져가면서 운영환경과 동일한 환경에서 개발할 수 있게 만들수 없을까? 라는 고민으로 삽질을 시작해보았다.
모든 예제는Github에 있습니다.

Step 1. Directory 설정

프로젝트 시작은 intellij를 사용하여 Spring project를 만들고 src폴더 밑에 front라는 vue 프로젝트를 만든다.

vue 3.* 생성 cli 명령어
Spring-vue 프로젝트 구조

 

 

Step2. Build 명령어 추가

프론트 프록시 서버를 띄워 개발하는 방법 (build --serve) *_이 아닌 *_build --watch를 통해 수정이 일어날 시 실시간으로 재빌드하도록 하기 위해 vue-cli-service 명령어package.json에 추가한다.

watch명령어에 vue-cli-service build --watch를 걸어놓으면 npm run watch를 실행할 수 있다.

 

 

Step3. OutputDir 설정

vue의 build파일을 spring의 resource 폴더 아래 정적 파일을 관리하는 static폴더에 빌드해야한다.

vue.config.jsfront 디렉토리 밑에 만들고 outputDir의 위치를 입력한다.

module.exports = {

  publicPath: '',

  outputDir: '../main/resources/static', // 빌드경로

  chainWebpack(config) { //빌드 시 빌드되어 나오는 js파일을 js폴더 아래로 묶어 빌드한다

    config.output.filename("js/[name].js"); 

  },

};

위 설정을 마치고 npm run watch를 실행해보면 아래와 같이 resource경로에 vue js 빌드 파일이 들어가 있는것을 확인할 수 있다.

실시간 변경내역들이 위 hot-update.json파일과 hot-update.js파일로 만들어져 추가된다.  

 

 

Step4. SinglePage Return

spring에서 static의 index.html을 내려주는 경로를 추가해 준다.

@Controller
@RequestMapping("/")
public class HomeController {

    @GetMapping
    public String index(){
        return "/index.html";
    }
}

이제 spring을 실행시켜 접속해보면 빌드한 vue 프로젝트를 볼 수 있다. watch가 걸린상태에서

그 다음은 환영합니다로 변경하고 spring을 재시작하면 vue의 추가된 내용을 빌드하면서 바뀐 문구를 볼 수 있을 것 입니다.

<template>
    <div>
        <p>환영합니다</p>
    </div>
</template>

<script>
    export default {
        name: "HomeView"
    }
</script>

<style scoped>

</style>

Step5. spring의 static-location 경로설정

여기서 한가지 문제는 vue의 코드를 바꾸면 항상 스프링을 재시작 해야한다는 점인데, 이럴경우에는devtools를 써서 hot reload를 제공해 줘도 되지만, devtools를 설정하는 번거로움과빌드되는 속도가 느리다는 단점이 있다.

그래서 spring의 static-location 경로빌드된 classpath가 아닌 resource 디렉토리를 보도록 yml에 설정을 추가한다.

* profile관리를 통해 local환경에서만 resources폴더를 바라보도록 해야한다.

application.yml

이렇게 static경로를 바꾼다면spring을 재시작할 필요없이 static파일이 변경된 부분을 새로고침만으로도 확인할 수 있다.

 

결론

하나의 포트로 개발하면vue js 개발환경을 운영환경과 똑같이 가져갈 수 있다는 장점이 있다.

예를들어 프론트에서 로그인을 요청하고 로그인이 성공한다면 서버사이드에서 홈으로 리다이렉트를 시킬것이다.

개발환경에서 두개의 포트로 띄운다면 요청한 프론트의 포트번호가 리다이렉트 될때는 서버사이드의 포트번호로 바뀌어 리다이렉트 될것이다.

위 문제는 vue.config.js의 설정을 통해 방지하거나, spring tomcat 설정을 통해 방지할 수 있다.

 

하지만...

삽질해본 결과 개발시에는 프록시서버를 띄워 프론트와 백엔드를 분리해서 개발하는 것이 더 편하다.

우선 빌드 결과가 실시간으로 메모리에서 변경되기 때문에 새로고침없이 페이지가 리로딩되는 편리함이 있다.

또 vue를 수정할때 마다리빌드된 파일들이 추가되기때문에 인텔리제이를 사용하고 있는 나에게는 계속해서 인덱싱하는 비용이 너무 크다고 느껴졌다.