프리온보딩 과정 중에서는 매번 팀프로젝트로 기업 과제를 수행해야 한다. 따라서 커리큘럼에 따라 지난 수업 이후에도 바로 과제가 나왔는데, 선발 시 진행했던 과제에 대한 Best Practice를 만들어오라는 것이었다.
지금껏 웹페이지 프로젝트에서는 기획부터 같이 진행하고, 무에서 유를 창조하는 것이었는데, 이번에는 각자 만든 것들을 토대로 최선의 것을 만들어오는 것이 과제였다.
처음에는 이전에 자신이 했던 것은 무시하고, 새롭게 컴포넌트 별로 역할 분배를 하는 것일까 생각했지만, 팀원들이 나 포함 7명이었고, 과제 제출 기간까지 이틀밖에 남지 않았기에 처음 생각했던 방식은 적절하지 않았다.
첫 과제여서 매우 혼란스러웠다. 그리고 멘토님께서 팀프로젝트라 생각말고, 동료학습에 집중하라 했는데, 처음에는 무슨 말인지 이해하지 못했다.(3주차가 막 지나는 지금 시점에서야 무슨 말인지 알 것 같다)
아무튼 자세한 사항은 제출 과제 레포지토리에 있으나 간단하게 진행 상황을 기록하자면 다음과 같다.
우선 첫 과제부터 삐걱됐다...
긴 호흡으로 진행되는 과제가 아닌만큼 빠르게 정하고, 정한 것에 대해 공유가 바로 돼야하는데, 그렇지 못했다.
일정이 있어서 처음 초기 설정에 대한 1시간 회의 이후 잠시 자리를 비웠는데, 그 사이에 나의 의견은 묻지 않고 typescript가 javascript로 바뀌어서, 돌아왔을 때 다소 언짢았다. 시간 관계 상 묻지 못했더라도 바꾸게 된 상황에 대한 설명이 기록으로 남았더라면 이해가 됐을 것이다.
더불어 긴 시간동안 무엇을 정해야하는지 갈피를 잡지 못해서 정말 답답했다. 사람이 7명인지라 각자 할 말만 했고, 정해지는 것이 거의 없었다. 그래서 처음 과제 중 코드 관련해서 의견을 하나라도 줄이는 것이 필요하다 느껴 코드를 작성하지 않고 README.md 작성과 배포를 맡았다.
[commit history]
중복 commit을 지양하고 본문도 적는 습관을 들이는 것이 좋다.
commit 본문에는 해당 작업을 왜, 어떻게 했는지 구체적으로 적어주는 것이 좋다.
👉 기업과제 평가 사항 중에서 git history도 포함되어 있기에 해당 부분도 유심히 보고 피드백을 주신 것 같다. 그리고 commit 본문은 생각해보면 한 번도 쓴 적이 없는데, 피드백을 들으니 본문을 쓰는 것이 팀에게도, 미래의 나에게도 도움이 될 것을 꺠달았다.
[.gitignore]
local에서만 쓰이는 것들(.env), editor 관련 설정 파일(.eslintcache)을 올리는 것은 잘못됐다. 만약 올라와야한다면 .env.sample
처럼 key값만 넣어놓거나 readme.md
에 잘 적어줘야한다.
[주석]
주석에 대한 견해는 다양할 수 있으나 절대적인 기준은 주석을 보지 않고도 코드가 읽혀야한다. 주석은 코드로 설명할 수 없는 부분만을 보충하게 된다. (ex. 배포 전에 처리해야 하는 부분을 TODO, FIXME로 표시)
🚨 제일 하면 안되는 것: 코드를 주석처리하는 것, git을 믿고 이력을 확인하는 것이 올바른 방법이다.
[README.md]
👍 목차를 통해 손쉽게 이동할 수 있도록 만든 점
👍 👀 코드에 대한 근거와 이유가 들면 어느 정도 먹고 좋게 평가한다.
👍 브랜치 전략, commit 컨벤션
👍 👀 테스트 계정을 미리 명시한다(로그인 기능이 있는 경우)
👍 👀 기능 명세를 적어놓은 점
👍 👀 기술 선택을 선택한 이유를
👍 👀 Best Practice 관련하여 PR 링크도 달아줬다.
👍 논의했지만 기각된 내용도 포함해서 적어둔 점
👉 이것 외에도 여러 가지 좋은 예시를 들어주셨는데, 여기서 👀 이 표시가 되어 있는 점은 전부 우리 팀에서 적용한 것들이다. 참고로 이번 과제 README.md는 내가 도맡아서 작성했다!!
아무도 칭찬 안해줘서 혼자 칭찬했다.
[Side Effect, 구조분해할당, 단축속성명]
{side effect}: 함수가 받은 input 받은 input 외에 다른 요소들에 접근하거나 수정하는 경우
👉 최대한 지양해야 한다. 외부에서 어떻게 쓰일 지 모르기 때문에 함부로 접근해서 수정하면 위험하므로, 카피해서 쓰고 return 하는 것이 안전하다.
{구조분해할당}: 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식
👉 쓸 수 있으면 쓰는 것이 가독성에 좋다.
[state 최소 집합 찾기]
다음의 것들은 state로 쓰면 안된다
😩 state의 속성으로 알 수 있는 값
😩 props
😩 시간이 지나도 변하지 않는 상수
[의존성]
변화에 유연하기 때문에 설정해주면 좋다. 예를 들어 localStorage 관리 시 storage라는 util 객체로 wrapping하면 추후 sessionStorage로 변경되었을 때 하나만 수정하면 된다.
[불필요한 Fragment, inline handler]
간단한 경우에는 컴포넌트 또는 태그에 inline으로 작성해도 괜찮지만 조금이라도 길어지면 가독성이 저하된다.
[서버란?]: 서버 === 무언가를 제공해주는 컴퓨터
On-Premise
서버를 운영하는 측에서 서버에 필요한 물리적인 공간, 컴퓨터, 제반 시설 등을 직접 구축해서 활용하는 방식
장점
단점
Cloud Computing
컴퓨터를 인터넷을 이용한 클라우드 서비스를 통해서 사용
장점
IaaS(Infrastructure as a Service)
대여받은 컴퓨터의 대부분의 리소스에 접근해서 서비스를 구성하고 관리 가능
많은 것을 할 수 있는 만큼 많은 것을 (설치, 환경 설정) 해줘야한다.
ex. AWS EC2
PaaS(Platform as a Service)
IaaS에 더불어 소프트웨어를 개발하고 운영하기 위해 필요한 구성요소들을 플랫폼화해서 제공해주는 서비스
운영에 대한 관리를 위임 가능
단점
해당 플랫폼에서 접근 허용하지 않는 부분은 제어 불가
특정 플랫폼에 종속적으로 될 수 있다
계층이 있기에 더 높은 비용을 지불해야할 수 있다
ex. AWS Elastic MeanStalk, Heroku, GitHub Pages
SaaS(Software as a Service)
클라우드 서비스에 더불어 고객이 이를 사용할 수 있는 소프트웨어가 함께 제공되는 형태
ex. DropBox, iCloud, Netflix, Google Apps, Slack
Amazon Web Service: 현재 전 세계에서 가장 많이 사용되고 있는 클라우드 컴퓨팅 서비스
요즘엔 AWS+Azure+GCP… 짬뽕임
주로 서비스에 필요한 이미지, 파일(정적 파일)을 안정적으로 제공할 수 있다.
index.html도 저장 가능→정적 웹사이트 호스팅에도 사용할 수 있다
CRA는 CSR
build 시 js, media, css만들어지고, 웹 브라우저에서 읽으면서 request
모든 컨텐츠를 클라이언트사이드에서 렌더링한다
SSR은 반면에 서버사이드에서 렌더링하고 보여준다.
실습
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<bucket-name>/*"
}
]
}
Continuous Integration과 Continuous Delivery / Deployment
코드를 지속적으로 통합해나가는 것
CI 과정에서 테스트를 실행하고 코드가 유효한지 검사하고 만약 문제가 발생했을 경우 즉각적으로 피드백을 통해 개발자가 문제를 확인하고 수정할 수 있게 만들어준다.
보통 CI는 PR 후 메시지가 온다(메일, slack, discord)
CI 과정을 통해 성공적으로 통합된 코드를 실제 사용자가 사용하고 있는 Production 환경에 배포하는 것
Delivery는 개발환경의 배포까지 자동화된 것을 의미
Deployment는 실제 사용자에게 제공되는 Production 환경까지의 배포를 자동화한 것을 의미
테스트가 확실하게 되어있어야 함
일련의 과정을 처리하는 파이프라인을 구축함으로서 자동화
설치형 파이프라인
특정 컴퓨터에 CI / CD 플랫폼을 설치해서 활용
ex. Jenkins
클라우드형
개발자가 직접 관리할 필요 없이 서비스 제공자가 클라우드에서 모두 운영해주는 형태
세부적인 조정이 불가능하다는 단점
요즘에는 클라우드를 쓰는 추세
ex. Travis CI, GitHub Actions
규모가 있는 개발팀의 경우 CI / CD를 구축하는 것이 보편적, 결국엔 효율때문
소프트웨어는 하드웨어에 비해 상대적으로 변경하기가 쉽다.
프로덕트를 더 좋은 방향으로, 더 빨리, 더 자주 개선하고자 할 때, 직접 수동으로 배포하는 과정에 리소스를 쏟기보다 프로덕트의 개발 및 개선 과정에 더 많은 리소스를 투입하는 것이 효율적이라고 판단
레파지토리 안에서 CI / CD까지 함께 구축하고 관리할 수 있다는 이점
Event
레파지토리에서 발생하는 특정한 활동, 특정한 Event가 발생했을 때 그에 맞는 CI / CD 파이프라인을 구동하도록 설정할 수 있다
ex. PR이 오픈되었을 때, master에 push되었을 때
Jobs
하나의 runner에서 실행될 여러 step(실행 가능한 하나의 shell script)의 모음
Actions
GitHub Workflow에서 자주 사용되는 기능들을 모아둔 일종의 커스텀 애플리케이션
사람들이 많이 쓰는 게 있다(마켓플레이스에)
Runner
일련의 작업(workflow)을 실행할 서버를 의미. 클라우드형 CI / CD 플랫폼인 GitHub Actions는 직접 컴퓨터를 관리할 필요 없이 가상의 Runner를 통해 Workflow 실행시켜줌
개발자는 자동화에 미쳐야 합니다.
- Repo 만들기
- project 만들기
- Actions 탭에 들어가기
- set up a workflow yourself 클릭
- /.github/workflows/deply.yml 생성
```bash
name: deploy
# event
on:
push:
branches:
- master
jobs:
deploy:
runs-on: ubuntu-latest
steps:
# action use
- uses: actions/checkout@master
# clean install의 줄임말
- run: npm ci
- run: npm run build
# action 이름 별도 지정 가능
- name: deploy to s3 bucket
# 마켓플레이스에 올라온 거 쓰자!
uses: jakejarvis/s3-sync-action@master
# 함수에 인자 넣어서 호출
with:
args: --delete
env:
AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: 'ap-northeast-2'
SOURCE_DIR: 'build'
```
기능 개발은 전체 프로세스의 일부분일 뿐입니다.
현대 IT팀에서 개발자는 기본적으로 제품의 기획 분석, 기능 개발, 배포 및 운영을 책임져야 하며 나아가서 제품의 기획단에도 참여해서 개발적으로 어떻게 요구사항들을 풀어나갈 수 있는지 의견을 낼 수 있어야 한다.
배포 및 운영까지 나의 책임이란 생각을 가져야지만 전체 개발 과정을 보는 시야가 길러진다.
그에 맞춰서 개발 일정을 조율하고 어떤 식으로 하면 배포와 운영을 안정적으로 할 수 있을까란 고민을 할 수 있게 된다.
다른 개발자에 비해 상대적으로 배포 운영의 비율이 적지만 할 수는 있어야 한다.
FE 개발자도 배포 과정에서 문제가 생겼을 때 어느 부분에서 문제가 발생했는지 확인하고 대응할 수 있어야 한다.
7명이서 동료 학습으로 기업 과제를 진행하는 것은 매우 비효율적이다. '동료 학습'을 원한다면 세션 전체 기간인 한 달 동안 다양한 기능을 담은 웹페이지를 계속해서 리팩토링하는 과정이 더 적합하다고 생각한다.
'사공이 많으면 배가 산으로 간다'라는 말을 몸소 느끼게 된 과제였다. 7명이 프론트와 백이면 모를까, 전부 프론트인데다가 하나의 과제를 만들어오는 과제는 효율적으로 이루어지기 매우 어렵다.
현직자 또는 멘토 격의 리더가 있었더라면 멘토님께서 원하는 방향으로 진행이 됐을 것 같은데 이런 식의 과제는 정말 혼란스러웠다.