All Articles

모던 프론트엔드를 배워 토이 프로젝트를 진행하고 배포하기

소스 코드: https://github.com/youngminz/exponential-backoff

토이 프로젝트 링크: https://youngminz.github.io/exponential-backoff/

2020.02.04 변경 사항

  • 구매한 도메인이 만료되어 본 블로그의 링크를 GitHub Pages 링크로 변경했습니다.

모던 프론트엔드 기술 학습하기

프론트엔드 기술에 관심이 생겼습니다. 프론트엔드를 정식으로 배웠던 건 6년 전 고등학교에서 배웠던 jQuery가 마지막이었습니다. 프론트엔드 세계에서 6년이라는 시간은 강산이 60번도 더 바뀌는 영겁의 세월입니다.

전반적인 프론트엔드 기술을 처음부터 다시 배워보기로 합니다. 아예 몰랐더라면 차라리 편할텐데, 애매하게 알고 있으니 오히려 배우는 데 방해가 되었습니다. 기초를 다지는 데 도움이 되었던 사이트와 책을 기록해 놓았으니, 이정표를 찾아 헤메는 분에게 조금이나마 도움이 되었으면 좋겠습니다.

  • poiemaweb.com - HTML5과 CSS3의 기초를 튜토리얼 방식으로 따라가면서 배울 수 있는 사이트입니다. 어설프게 알고 상태에서 제대로 다시 배우는 건 생각보다 어려웠습니다.
  • javascript30.com - 바닐라 모던 자바스크립트로 30개의 여러 가지를 만들어 보는 강의입니다. 프론트엔드 고수가 라이브 코딩하는 걸 따라해 볼 수 있는데, 많은 인사이트를 받았습니다. 강의 시간도 30분 내외로 짧아서 자바스크립트 교양으로 듣기 좋았습니다.
  • 실전 리액트 프로그래밍 - React를 처음 접하는 사람도 따라할 수 있도록, React 및 ReactDOM의 기초 개념부터 webpack 및 next.js 고급 단계까지 담은 책입니다. jQuery 방식의 Procedural 방식으로 생각하는 것에서 벗어나, React 방식의 Declarative 방식으로 생각할 수 있게 도움이 많이 되었습니다. 개인적으로 훈련소에 가져가서 심심할 때마다 읽었습니다 ㅎㅎ

기존에 완전 잘못 알고 있었던 개념 중 하나는 var 뿐만 아니라 constlet도 호이스팅이 된다는 점이었습니다. Temporal Dead Zone 이라는 개념 때문에, 아래의 코드는 오류가 발생합니다. 즉 호이스팅이 된 부분부터 실제로 constlet으로 선언된 부분 사이에서 해당 변수를 사용하면 ReferenceError가 발생합니다. 참으로 알쏭달쏭한 자바스크립트입니다.

{
	const number = 1;
	{
		console.log(number);
		const number = 2;
	}
}

=> Uncaught ReferenceError: Cannot access 'number' before initialization

토이 프로젝트 선정하기

네트워크 통신은 실패할 수 있습니다. 그래서 실패를 인정하고 재시도하는 전략이 중요합니다. 쉴 틈 없이 계속해서 재시도하면 서버에 엄청난 과부하가 걸립니다. 이를 막기 위해 Exponential backoff 알고리즘을 사용합니다.

이 알고리즘을 시뮬레이션을 해 주는 사이트를 찾아보았습니다. http://backoffcalculator.com/ 사이트가 나왔습니다. 왠지 더 잘 만들 수 있을 것 같습니다. 토이 프로젝트 주제로 잡았습니다.

코딩하기

create-react-app 으로 프로젝트를 시작했습니다. React로 HTML 코딩도 하고, CSS 코딩도 했습니다. Input 컴포넌트를 작업하는 부분에서 막혔습니다. 회사의 프론트엔드 동료 분께 도움을 요청드렸더니, 감사하게도 흔쾌히 작업을 진행해 주시고 Pull Request까지 만들어 주셨습니다. 기쁜 마음으로 Merge 하였습니다.

인프라를 설정하고 자동 배포하기

이 부분이 제일 까다로운 부분입니다. 다행히 설정할 때 기록해 두어서 자세히 공유할 수 있었습니다.

도메인 구매

AWS Route 53에서 구매했습니다. 개인 정보를 넣게 되어 있는데 보호 서비스를 켜 두면 Whois에서 개인정보가 조회되지 않습니다. 콘솔에서 하라는 대로 하면 됩니다. 구매부터 검증 완료까지는 16분 정도 소요되었습니다.

깃허브 페이지와 연계하기

커스텀 도메인에 앞에 www. 를 붙인 도메인을 사용하도록 했습니다. 이렇게 하면 gh-pages 브랜치의 CMANE 파일이 만들어집니다. 이 때, package.json에서, predeploy 스크립트에 아래처럼 CNAME 파일을 만드는 스크립트를 넣어서, 빌드 시에 저 파일이 사라지지 않게 했습니다. 저게 사라지면 GitHub 커스텀 도메인 호스팅이 끊깁니다.

"predeploy": "npm run build && echo www.backoffsimulator.com > build/CNAME"

GitHub Pages 뿐만 아니라, Route 53 설정을 해야 도메인이 정상적으로 작동하기 시작합니다. 아래의 도메인으로 들어왔을 때, https://www.backoffsimulator.com 으로 리다이렉션 시키는 방법을 찾아 보았습니다.

https://www.backoffsimulator.com: CNAME youngminz.github.io 으로 설정하면 됩니다. 간편합니다.

http://www.backoffsimulator.com: GitHub에서 Enforce HTTPS 옵션을 켜면 됩니다. 역시 간편합니다.

http://backoffsimulator.com & https://backoffsimulator.com: 까다롭습니다. www가 붙지 않은 최상위 도메인은 CNAME이 지원되지 않습니다. 그래서 A레코드를 이용해야 합니다. S3 정적 웹 사이트 호스팅을 이용하는 방법과, CloudFront + S3 정적 웹 사이트 호스팅을 이용하는 방법이 있습니다.

  • S3 정적 웹 사이트 호스팅

    1. backoffsimulator.com 처럼 S3와 연결하려는 도메인 명으로 버킷을 만듭니다.
    2. S3 Properties에서 아래처럼 설정합니다.

    1. Route 53에서 이 S3 버킷을 바라보도록, A 레코드를 생성합니다. S3 website endpoints 에서 찾아서 연결하면 됩니다.

    이 방법은 간편하기는 하지만, https 지원이 안 됩니다. 즉, http://backoffsimulator.com 을 리다이렉션하는 경우는 성공하지만, https://backoffsimulator.com 을 설정할 수 없습니다.

  • CloudFront + S3 정적 웹 사이트 호스팅

    1. S3 버킷을 만듭니다. 이 때, 버킷 명에 . 이 들어가면 https 인증서 오류가 발생하니 . 를 빼고 만들어줍니다.
    2. CloudFront Distribution을 만듭니다. 이 때, Endpoint를 그냥 목록에서 찾아서 하면 Access Denied가 뜹니다. 반드시 Static website hosting 엔드포인트로 설정해줍시다. HTTPS ACM 인증서도 발급해서 커스텀 도메인을 사용할 수 있게 해줍시다.
    3. Route 53에서 CF 바라보게 설정하면 됩니다.

CloudFront + S3 정적 웹 사이트 호스팅 방법으로 진행하면, http://backoffsimulator.comhttps://backoffsimulator.com 는 이제 https://www.backoffsimulator.com 으로 리다이렉트 됩니다.

GitHub Action으로 CD 구축하기

쉽습니다.

name: gh-pages

on:
  push:
    branches:
      - master
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@master
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
    - name: deploy
      run: |
        git remote set-url origin https://youngminz:${{ secrets.GITHUB_TOKEN }}@github.com/youngminz/exponential-backoff.git
        git config --global user.email "youngminz.kr@gmail.com"
        git config --global user.name "Youngmin Koo"
        yarn
        yarn deploy