본문 바로가기
개발자의 정보/JS & framework

Spring-boot maven with @vue/cli 으로 웹 서비스 만들기

by pastory 2020. 2. 1.

서버는 spring-boot를 사용하고 웹은 vue를 이용하기 위해 다음과 같은 몇가지 과정을 거쳐야 합니다.

  • 스프링부트 프로젝트 구성
  • Controller 매핑 설정
  • vue 프로젝트 구성
  • vue config 설정
  • frontend 메이븐 플러그인 추가

이 과정을 풀어서 이 글을 읽으시는 분들 누구나 따라할 수 있도록 남겨 보려고 합니다.

1. 스프링 프로젝트 구성

우선 사용하시는 IDE에는 기본적으로 spring-initializer 가 탑재 되어 있을 것입니다. 지금 이 글을 찾아 들어오시는 분들이라면 기본적으로 spring-boot 프로젝트 생성에는 문제가 없을 것으로 생각 되므로 이 부분은 그냥 넘어 가도록 하겠습니다.

단! vue 실행시 spring 기본 웹 포트와 같은 포트로 실행되기 때문에 스프링 프로젝트를 만드신 후에는 반드시 개발용 포트를 따로 지정하시거나 vue 에서 웹 서비스 포트를 변경하셔야 합니다. 저는 보통 application.properties 를 개발용과 배포용을 따로 만들어 사용하는데 따로 구분해서 사용하는 방법은 따로 포스팅 하도록 하겠습니다.

여기서는 application.properties 파일에 server.port=33080 으로 설정하고 진행 하도록 하겠습니다.

2. Controller 매핑 설정

웹페이지 연결을 vue를 이용할 것이기 때문에 서버 api로 사용되지 않는 모든 url에 대해서 /index.html 페이지로 연결 되도록 설정해야 합니다. 그러기 위해서는 spring-boot 프로젝트 안에 컨트롤러를 만들어 url 매핑을 해 주어야 합니다.

기본 패키지 혹은 web controller를 모아 사용할 패키지에 DefaultController.java 파일을 생성하여 아래와 같이 모든 URL에 대하여 Get 방식의 요청은 index.html 페이지로 연결되도록 합니다.

@Controller
public class DefaultController {

    @GetMapping(value = {""}, produces = {"text/html"})
    public String index(HttpServletRequest req) {
        return "index.html";
    }
}

3. @vue/cli 프로젝트 구성

실제 사용자에게 보여질 웹 페이지는 vue/cli 를 활용하여 만들도록 합니다. 그러기 위해서는 vue 그리고 vue/cli 에 관련한 간단한 정보가 필요하겠죠. vue (https://kr.vuejs.org/) 를 좀더 쉽게 사용하기 위해 @vue/cli (https://cli.vuejs.org) 프로젝트가 만들어 졌기 때문에 @vue/cli를 vue 관리 패키지 매니저 라고 생각하시면 될 것 같습니다.

또한 이러한 프론트 개발을 위해 NodeJS(https://nodejs.org/ko/)가 설치 되어 있어야 합니다. 일반적으로 그냥 다운로드 하여 설치 실행하면 되니 따로 언급하지 않겠습니다.

NodeJS가 설치 되어 있다면 아래의 과정을 따라 진행하시면 됩니다.

@vue/cli 설치

@vue/cli를 글로벌로 설치합니다. 그래야 언제 어디서든 vue ui 명령으로 관리창을 열 수 있으니까요.

cd {프로젝트 경로}/src/main
yarn global add @vue/cli
// OR
npm install @vue/cli -g

frontend 프로젝트 생성

vue 프로젝트를 만들고 만들어진 프로젝트 디렉토리로 들어갑니다.

vue create frontend
cd frontend

vue add-on 설치

vue 프로젝트에서 사용할 애드온들을 설치합니다. 이번 경우는 제가 주로 사용하는 vuetify, router, vuex 를 설치하는 예제입니다. 사실 이거 외에도 설치할 애드온들은 더 있긴 해요. 하지만 간단한 프로젝트라면 이정도로 충분합니다.

vue add vuetify
vue add router
vue add vuex

4. vue config 설정

src/main/frontend 디렉토리에 vue.config.js 파일을 만들어 기본적인 설정을 해 주어야 합니다. 테스트 없이 바로 배포된다면 outputDir 경로만 지정해 주어도 npm run build 실행시 저장된 경로에 index.html 파일과 함께 배포 파일들이 저장됩니다.

module.exports = {
   outputDir: '../resources/static'
}

하지만 개발이 테스트 없이 되지는 않겠지요. 그렇기 때문에 추가 설정을 해 주어야 합니다. 서버에서 필요한 정보를 받아오기 위해 일부 요청은 서버로 보내서 받아야 하니까요.

서버에서 쿠키를 사용할 때를 위해 쿠키도 동기화 해주는 replaceCookie 를 추가하여 요청을 서버로 전달하거나 받을 때 쿠키를 동기화 해 주도록 합니다. 추가로 /sse, /api, /sign, /resource 등의 서버로 연결이 필요한 모든 연결에 대해 서버로 요청을 보낼 수 있도록 설정해 줍니다.

'use strict';

// https://webpack.js.org/configuration/dev-server/#devserver-proxy

const targetHost = 'localhost';
const targetPort = 33080;

const port = 8080;
let cookie;

const replaceCookie = function(cookie) {
    return cookie
        .replace(/\s+domain=[^\s;]+;?/, '')
        .replace(/\s+secure;?/, '')
};

module.exports = {
  outputDir: '../resources/static',

  devServer: {
    port: port,
    clientLogLevel: 'debug',
    historyApiFallback: true,
    hot: true,
    inline: true,
    publicPath: `http://localhost:${port}/`,
    transportMode: 'sockjs',
    headers: {
      'Access-Control-Allow-Origin': '*'
    },
    proxy: {
      '^/ws': {
        target: `http://${targetHost}:${targetPort}`,
        changeOrigin: true,
        ws: true,
        onProxyReq: (proxyReq) => {
          if (proxyReq.getHeader('origin')) {
            proxyReq.setHeader('origin', `http://${targetHost}:${targetPort}`);
          }

          if (proxyReq.getHeader('set-cookie')) {
            proxyReq.headers['set-cookie'] = proxyReq.headers['set-cookie'].map(replaceCookie)
          }

          if (cookie) proxyReq.setHeader('Cookie', cookie);
        },
        onProxyRes: (proxyRes) => {
          if (proxyRes.headers['set-cookie']) {
            cookie = proxyRes.headers['set-cookie'] = proxyRes.headers['set-cookie'].map(replaceCookie)
          }
        },
      },
      '^/(sse|api|sign|resources)': {
        target: `http://${targetHost}:${targetPort}`,
        changeOrigin: true,
        onProxyRes: (proxyRes) => {
          if (proxyRes.headers['set-cookie']) {
            cookie = proxyRes.headers['set-cookie'] = proxyRes.headers['set-cookie'].map(replaceCookie)
          }
        },
      }
    }
  },

  pluginOptions: {
    moment: {
      locales: ['ko_kr']
    }
  }
};

여기까지 진행하셨다면 이제 개발은 순조롭게 진행할 수 있습니다. 아까 vue 프로젝트를 생성하기 위해 열어둔 command line에 $ npm run serve 명령을 해 보세요. 아래와 같은 화면을 볼 수 있다면 vue 프로젝트가 동작한다는 뜻입니다.

그리고 IDE 기능이나 mvn spring-boot:run명령을 통해 spring-boot 도 실행해 보세요.

5. frontend maven plugin 추가

이제 마무리 입니다. 배포하기 위해 패키징을 할 때 frontend 파일들이 빌드되어 springboot 프로젝트의 src/main/resources/static 디렉토리에 들어가 주어야 합니다.(vue.config.js 만들어 수정한거 기억 하시죠?) 그래야 배포된 spring-boot 프로젝트가 실행될 때, 개발하면서 확인한 내용과 똑같이 작동할 수가 있습니다.

다행히 이 작업을 자동화 해둔 플러그인이 있습니다. frontend-maven-plugin 입니다. 이것만 적용하면 spring-boot 프로젝트를 패키징 할 때 자동으로 frontend 프로젝트를 빌드하고 난 후에 패키징이 진행 됩니다.

${project.dir}/pom.xml 에 를 찾아 다음과 같은 플러그인을 추가합니다. version, nodeVersion, npmVersion 항복은 자신에 맞게 수정하셔야 합니다. nodeVersion은 node --version 명령으로, npmVersion은 npm --version명령으로 확인하실 수 있습니다.

<plugin>
   <groupId>com.github.eirslett</groupId>
   <artifactId>frontend-maven-plugin</artifactId>
   <version>1.6</version>
   <configuration>
      <workingDirectory>${project.basedir}/src/main/front</workingDirectory>
      <nodeVersion>v10.4.0</nodeVersion>
      <npmVersion>6.4.1</npmVersion>
      https://nodejs.org/dist/
      http://registry.npmjs.org/npm/-/
   </configuration>

   <executions>
      <!-- Install our node and npm version to run npm/node scripts-->
      <execution>
         <id>install node and npm</id>
         <goals>
            <goal>install-node-and-npm</goal>
         </goals>
      </execution>

      <!-- Install all project dependencies -->
      <execution>
         <id>npm install</id>
         <goals>
            <goal>npm</goal>
         </goals>
         <!-- optional: default phase is "generate-resources" -->
         <phase>generate-resources</phase>
         <!-- Optional configuration which provides for running any npm command -->
         <configuration>
            <arguments>install</arguments>
         </configuration>
      </execution>

      <!-- Build and minify static files -->
      <execution>
         <id>npm run build</id>
         <goals>
            <goal>npm</goal>
         </goals>
         <configuration>
            <arguments>run build</arguments>
         </configuration>
      </execution>
   </executions>
</plugin>

여기까지 하셨으면 모든 과정을 마치셨습니다. 이제 버그는 없는지 혹시 오타등으로 인해 잘못 실행되는 부분은 없는지 체크해 보시면 됩니다. 모든게 정상 작동 한다면 maven 패키징을 실행하여 패키징된 jar 파일 혹은 war 파일을 실행해 정상적으로 화면이 나오는지 확인해 보시면 됩니다.

여기까지가 spring-boot 프로젝트와 @vue/cli 프로젝트를 구성하여 함께 개발하고 배포하는 방법입니다. 혹시 도움이 되셨다면 작은 댓글이라도 한 줄 부탁드리겠습니다. 그럼 20000.

댓글