16 –애플리케이션 실전 파트– 서비스 배포 환경 구성

source: categories/study/vue-beginner-lv3/vue-beginner-lv3_9-07.md

16.1 서비스 배포를 위한 명령어 소개 및 실습

CLI로 생성한 프로젝트 배포하기

배포 명령어


npm run build
# OR
yarn build

CLI로 생성한 프로젝트를 서비스에 배포하려면 제일 먼저 위 명령어를 실행해야 합니다.
실행하고나면 dist 폴더에 호스팅할 수 있는 형태의 HTML, CSS, JavaScript, 이미지 등의 파일이 생성됩니다.
이렇게 생성된 자원을 빌드된 자원이라고 부릅니다.

16.2 Netlify를 이용한 배포 실습

GitHub 서비스를 이용하기 위해 GitHub 계정으로 Sign Up 한다.

New site from Git 버튼을 통해 배포를 해보겠다.

클릭하고나면 사이트 생성 관련 step들이 3가지가 나온다.
우리가 형상관리를 해줄건데 넌 어떤거를 통해 형상관리를 하고싶니? 라고 물어보는 것이다.
우리는 GitHub을 사용할 것이므로 GitHub을 클릭하면된다.

권한을 부여하고 배포를 원하는 저장소를 선택 후

위와 같이 base folder, build 명령어, publish folder 이름을 입력하고 Deploy Site 버튼을 클릭한다.

실패했네..
왜 실패했을까?
Site deploy failed를 한번 클릭해보자.

위에서 Production: master@HEAD Failed를 클릭하자.

Base directory does not exist: /opt/build/repo/dist

Base directory 경로가 잘못된 것 같다.

16.3 base 디렉토리 설정 및 배포 완료

위 화면에서 Deploy settings 버튼을 클릭하자.

그럼 이런식의 Build settings 정보가 나온다.
위에 보시면 Publish directory에 아무것도 세팅이 안되어있다.
이 부분을 Edit settings 버튼을 클릭해 바꿔보도록 하겠다.

위 배포할 레포 및 브랜치를 보시면 바로 root 폴더에 dist 폴더가 있는 것이 아니다.
vue-news 폴더 안에 dist 폴더가 존재한다.
이 점이 고려가 안되어있었기 때문에 에러가 난 것이다.

위와 같은식으로 수정한다.

다시 Deploys 메뉴로 돌아가셔서

Trigger deploy를 클릭하여 Clear cache and deploy site를 클릭해보자.
그럼 빌드가 잘 될 것이다.

Preview 버튼을 통해 배포완료된 페이지를 확인할 수 있다.

브랜치도 수정해주자.
그리고 다시 deploy하자.

16.4 SPA 호스팅시에 서버에 추가해줘야 하는 설정 안내

라우팅을 설정했을 때 서버쪽에 어떤 설정을 해야되는지 같이 살펴보도록 하겠습니다.
public/_redirects 파일 없으면 라우터 에러가 날 수 있습니다.

위와 같이 public/_redirects 파일을 추가했습니다.
이게 뭐냐면, Single Page Application라고 하는 것은 특정 페이지의 정보를 서버에서 받아오는 것이 아니라
미리 저희가 다 갖고 있다가 필요시에 그 페이지로 자바스크립트를 통해 전환하는 것이라고 말씀을 드린적이 있습니다.

/ask라고 입력했을 때, 서버에서 알 길이 없다.
무슨 소리냐면 /ask에 대한 페이지 정보는 브라우저에 있다는 것이다.
다시말해 클라이언트에 정보가 있는데, 서버에서 이 클라이언트 정보를 알 수가 없다는 것이다.

따라서 서버에서는 이러한 path들.. /jobs, /news 이러한 브라우저(클라이언트)만 알고있는 정보들을 알려줘야될 필요성이 있다.
이런거에 대해서 서버에 따로 설정을 해줘야되는데,

기본적으로 특정 도메인 뒤에 오는 위와 같은 url들을

# Netlify settings for single-page application
/*    /index.html   200

_redirects라는 위와 같은 파일을 쓰시게되면, 모든 접근에 대해서 index.html로 돌리겠다 라는 뜻.. 위와 같은 설정을 서버마다 다 해주셔야됩니다.

위 파일을 public 파일 안에 _redirects라는 이름으로 넣으면되고,,,

위 파일 내용은 Netlify에서는 서버 설정을 /index.html로 하겠다는 뜻입니다.

따라서 현재 저희가 많이 사용하는 것이 Amazon S3, Github pages, Firebase 등등 많은데,
각각의 서버설정.. 그러니까 웹서버라고하는 서버의 이러한 설정들을 해주시지않으면,
라우팅을 클라이언트 사이드에서 했을 때,
다시 말하면 Single Page Application을 구성했을 때,
서버에서 페이지를 찾을 수 없다라고 먼저 서버가 응답을 해버리게됩니다.

그래서 그러기전에 미리 서버 설정을 보고 위와 같이 설정을 꼭 해주시기 바랍니다.

16.5 env 환경 변수 파일을 이용한 옵션 변경 방법

환경 변수 파일을 이용한 옵션 설정

제작한 코드를 서버에 배포할 때 환경 변수로 편하게 특정 값들을 바꿀 수 있는 방법에 대해 알아보겠습니다.

env 파일

CLI로 생성한 프로젝트로 개발 및 배포를 진행할 때 .env라는 환경 변수 파일로 옵션들을 편하게 바꿀 수 있습니다.
옵션들을 담아놓는 파일이라고 생각하시면 됩니다.
일반적으로 브라우저에 값을 노출하고 싶지 않을 때, 이런 .env 파일에 담아서 몰래 관리하는 방법도 있습니다.
.env 파일을 가지고 값을 조정해서 뿌리는 것도 해보도록 하겠습니다.

# .env 파일
VUE_APP_LOCAL_URI=http://localhost:8080/
VUE_APP_TEST_SERVER=http://test.com:9090/

clientId=client-test1234
clientServer=server-test1234

실습

src/App.vue



<template>
  <div id="app">
    <tool-bar></tool-bar>
    <transition name="page">
      <router-view></router-view>
    </transition>
    <spinner :loading="loadingStatus"></spinner>
  </div>
</template>

<script>
import ToolBar from "./components/ToolBar";
import Spinner from "./components/Spinner";
import bus from "./utils/bus";

export default {
  name: 'App',
  components: {
    ToolBar,
    Spinner,
  },
  data() {
    return {
      loadingStatus: false,
    }
  },
  methods: {
    startSpinner() {
      this.loadingStatus = true;
    },
    endSpinner() {
      this.loadingStatus = false;
    },
  },
  created() {
    console.log(process.env.APP_TITLE);
    bus.$on('start:spinner', this.startSpinner);
    bus.$on('end:spinner', this.endSpinner);
  },
  beforeDestroy() {
    bus.$off('start:spinner', this.startSpinner);
    bus.$off('end:spinner', this.endSpinner);
  }
}
</script>

<style>
body {
  padding: 0;
  margin: 0;
}
a {
  color: #34495e;
  text-decoration: none;
}
a.router-link-exact-active {
  text-decoration: underline;
}
a:hover {
  color: #42b883;
  text-decoration: underline;
}

/* Router Transition */
.page-leave-active {
  transition: opacity .5s;
}
.page-leave-to /* .page-leave-active below version 2.1.8 */ {
  opacity: 0;
}

.page-enter-active {
  transition-delay: .5s;
  transition-property: opacity;
  transition-duration: .5s;
  /*transition: opacity 5s;*/
}
.page-enter {
  opacity: 0;
}
.page-enter-to /* .page-leave-active below version 2.1.8 */ {
  opacity: 1;
}
</style>


.env



# Temp
APP_TITLE=HELLO


이렇게 작성하면 console 창에 undefined가 찍힌다.
이를 인식하게하려면 원래 예전엔 webpack define plugin을 사용했었다.




# .env 파일
VUE_APP_LOCAL_URI=http://localhost:8080/
VUE_APP_TEST_SERVER=http://test.com:9090/

clientId=client-test1234
clientServer=server-test1234




// webpack.config.js
const webpack = require('webpack');
const dotenv = require('dotenv');
const env = dotenv.config().parsed;

plugins: [
    new webpack.DefinePlugin({
        VUE_APP_LOCAL_URI: JSON.stringify(env.VUE_APP_LOCAL_URI),
    }),
],



그런데 위와 같은 작업을 하지 않아도 vue-cli 3점대 버전을 사용하시면..
webpack define 코드는 2점대 버전에서 사용했었던 코드이고, 지금도 쓸라면 쓰겠지만..



<template>
  <div id="app">
    <tool-bar></tool-bar>
    <transition name="page">
      <router-view></router-view>
    </transition>
    <spinner :loading="loadingStatus"></spinner>
  </div>
</template>

<script>
import ToolBar from "./components/ToolBar";
import Spinner from "./components/Spinner";
import bus from "./utils/bus";

export default {
  name: 'App',
  components: {
    ToolBar,
    Spinner,
  },
  data() {
    return {
      loadingStatus: false,
    }
  },
  methods: {
    startSpinner() {
      this.loadingStatus = true;
    },
    endSpinner() {
      this.loadingStatus = false;
    },
  },
  created() {
    console.log(process.env.VUE_APP_TITLE);
    bus.$on('start:spinner', this.startSpinner);
    bus.$on('end:spinner', this.endSpinner);
  },
  beforeDestroy() {
    bus.$off('start:spinner', this.startSpinner);
    bus.$off('end:spinner', this.endSpinner);
  }
}
</script>

<style>
body {
  padding: 0;
  margin: 0;
}
a {
  color: #34495e;
  text-decoration: none;
}
a.router-link-exact-active {
  text-decoration: underline;
}
a:hover {
  color: #42b883;
  text-decoration: underline;
}

/* Router Transition */
.page-leave-active {
  transition: opacity .5s;
}
.page-leave-to /* .page-leave-active below version 2.1.8 */ {
  opacity: 0;
}

.page-enter-active {
  transition-delay: .5s;
  transition-property: opacity;
  transition-duration: .5s;
  /*transition: opacity 5s;*/
}
.page-enter {
  opacity: 0;
}
.page-enter-to /* .page-leave-active below version 2.1.8 */ {
  opacity: 1;
}
</style>




# Temp
VUE_APP_TITLE=HELLO


위와 같이 앞에 VUE_ 프리픽스를 붙이면 따른 추가 설정 안해도 잘 인식한다.