[1] 요구사항 분석
1. 가계부 서비스spec과 user story 개념 정리
가계부 서비스 Spec
- 소비 내역을 관리하여 나의 자산현황을 파악하고 이전 기록을 확인하는 목적
- main 컨셉
- 현재 자산을 관리할 수 있음
- 소비 내역을 관리할 수 있음
- Entity와 속성
- entity : 식별할 수 있는 대상으로 정리한 것
- 자산
- id, 금액, 최초 생성일자, 수정 일자
- 소비 내역
- id, 금액, 카테고리, 내용, 시점 금액, 생성 일자
User Story의 정의
- 유저의 목표 달성을 위한 인터렉션을 하나의 문장으로 정리한 것
- {{ 사용자 }}는 {{ 무언가 }}를 위해 {{ 무언가 }}를 할 수 있음
User Story
: main 컨셉에서 디테일하게 세분화

- 현재 자산을 관리할 수 있음
- 현재 자산을 조회할 수 있음
- 현재 자산을 등록할 수 있음

- 소비 내역을 관리할 수 있음
- 소비내역을 등록할 수 있음
- 소비내역을 수정할 수 있음
- 소비내역을 삭제할 수 있음
2. User Flow와 상세 Flow
User flow
- user story를 기준으로, 구현 시나리오를 정리한 것
- 원칙
- 유저의 행동을 시작으로 시나리오가 시작
- 유저의 행동에 따른 피드백을 제공해야 함
- 시나리오 성공 case를 먼저 작성
- 시나리오가 실패되는 case를 나열
- 실패 case == 엣지 케이스
- 시나리오의 조건들을 나열하고, 조건별로 실패가능한 케이스를 정리
가계부 서비스 - User flow
- 소비 내역을 관리할 수 있음 > 소비 내역을 등록할 수 있음
- 필수 조건 : 자산 존재 여부, 자산 금액
- 성공 시나리오 :
- 유저는 자산이 0원 이상 있는 경우 소비내역을 등록할 수 있음
- 실패 시나리오 :
- 유저는 자산이 0원 미만이면 소비내역을 등록할 수 없음
- 우저는 자산보다 많은 금액을 소비내역에 등록할 수 없음
가계부 서비스 - 상세 Flow
- 소비 내역을 관리할 수 있음 > 소비 내역을 등록할 수 있음
- 필수 조건 : 자산 존재 여부, 자산 금액
- 성공 시나리오 : 유저는 자산이 소비할(한) 내역 이상 있는 경우 소비내역을 등록할 수 있음
- 실패 시나리오 : 유저는 자산이 소비할(한) 내역 미만이면 소비내역을 등록할 수 없음
- 자산을 조회
- 자산이 0원 이상이면, 소비내역을 등록할 수 있는 입력 form을 볼 수 있음
- 자산이 0원 미만이면, 소비내역을 등록할 수 있는 입력 form을 볼 수 없음
소비내역 등록 시, 자산보다 같거나 적은 금액을 등록할 수 있음
가계부 서비스 - 상세 Flow - diagram

- 소비 내역을 관리할 수 있음 > 소비 내역을 등록할 수 있음
- 필수 조건 : 자산 존재 여부, 자산 금액
- " 유저는 자산을 확인한 후, 소비내역을 입력하여, 다시 계산된 자산을 확인할 수 있다 "
가계부 서비스 - 상세 Flow - 의사코드
if( 자산 < 0 ) {
return input.hidden()
} else {
input.show();
}
submit();
const submit = () => {
if( 자산 < 소비내역 ) {
return submitFail;
}
else {
submitSuccess;
get자산();
}
}
- 의사코드 pseudocode
- 일반적인 언어로, 코드를 흉내내어 알고리즘을 써놓은 코드
- 흉내만 낸 코드. 모델링 시 사용
3. tech spec
tech spec
1. 서비스에 접근
- 구현 목표 : 유저가 브라우저에서 화면을 확인할 수 있도록 함
- 필요
- 유저가 브러우저에 접근
- 유저가 확인할 수 있는 화면이 그려짐
- tech flow
- 브라우저를 사용하여 서비스 url에 접속
- 서비스에 필요한 파일을 load(파일을 가져옴)함
- load한 파일들을 활용하여 화면을 그림
- 유저가 액션을 하면, 서비스는 액션을 입력받음
- 구현 목표 : 유저의 액션을 서비스에서 입력받음
- 필요
- 유저가 액션할 수 있는 UI
- 유저의 액션을 입력받을 수 있도록 준비
- tech flow
- input UI에 키보드로 숫자를 입력
- input에 등록된 이벤트가 실행됨
- 입력받은 데이터를 브라우저에서 확인할 수 있음
- 입력받은 데이터를 서버에 저장
- 구현 목표 : 유저에게 입력받은 데이터를 서버에 저장
- 필요
- tech flow
- 유저가 버튼을 클릭
- 버튼에 등록된 서버 전송 이벤트가 발생됨
- API를 통해 서버에 데이터 저장을 요청
- 서버는 요청사항이 완료되면, 브라우저에게 알려줌
- 현재 자산을 서버로부터 받아옴
- 구현 목표 : 현재의 자산 데이터를 서버로부터 받아옴
- 필요
- tech flow
- 1. API를 통해 서버에 데이터 조회를 요청
- 2. 서버에서 데이터를 응답해줌
- 서버로부터 받은 자산 데이터를 화면에 보여줌
- 구현 목표 : 서버로부터 응답받은 데이터를 화면에 보여줌
- 필요
- 서버로부터 응답받은 데이터
- 응답 데이터를 유저가 보기 쉽게 처리하느 ㄴ로직
- 유저가 확인할 수 있는 화면 그리기
- tech flow
- 응답 데이터를 유저가 보기 쉽게 처리
- 처리된 데이터를 화면에 다시 보여줌
3가지 레이어
: 웹/유저/서버 간 인터렉션

- 웹 → 유저 : 화면을 보여줌 (렌더링)
- 웹 ← 유저 : 액션 입력을 받을 수 있도록 함
- 웹 → 서버 : 데이터 조회/저장/수정 요청
- 웹 ← 서버 : 요청사항에 대한 응답을 받음
1) 렌더링 레이어
렌더링
-
기본 렌더링
- html 파일에서 문서를 작성
- 최초 파일이 로드될 때, 브라우저에 의해 html을 읽어 화면에 그림
-
런타임 때 렌더링
- 런타임 때 JS로 렌더링을 조작
- 액션이 있을 때 UI를 변경해야 하는 case
(1) html을 통한 렌더링
- html파일, css파일, DOM의 개념
- html
- Hyper Text Markup Language의 약자
- 웹페이지와 웹사이트의 구조를 구성하는 코드(마크업)
- 웹을 로드할 때 처음에 로드하는 파일
- < div >< /div > (- 태그를 통해 구분)
- CSS
- Cascading StyleSheet
- 마크업 언어가 실제로 표시되는 방법을 기술하는 스타일 언어
- 선택자 { ... }
- DOM
- Document Object Model
- html 문서와 상호작용할 수 있는 인터페이스
- node와 object로 문서를 표현
- 트리 구조 : 부모/자식의 관계가 형성됨
렌더링 과정

1. html 마크업 파싱 - DOM 트리 구축(Document Object Model)
2. CSS 마크업 파싱 - CSSOM 트리 빌드(CSS Obejct Model)
3. DOM과 CSSOM을 결합하여 렌더링 트리 형성
4. 렌더트리 배치
5. 렌더트리 페인팅
(2) 런타임 때 렌더링 조작
- triggering이 있을 때 UI를 변경해야 하는 case
- 런타임때 자바스크립트로 DOM을 조작하여 렌더링
- 리렌더링 - 리페인팅, 재배치 발생
- 자바스크립트로 DOM노드 선택
- 노드 조작
1) 선택한 노드에 새로운 노드를 추가
2) 선택한 노드를 수정/삭제
-> Document 인터페이스를 통해 접근
런타임 때 렌더링 조작 - DOM 노드 선택
document.querySelector(선택자)
document.querySelector(".className")
document.querySelector("#idName")
querySelector, querySelectorAll, getElementById, ...
런타임 때 렌더링 조작 - 노드 조작
- 노드 생성
- document.createElement(태그 이름)
- 노드 추가
2) 이벤트 등록
유저가 클릭을 했을 때, 함수를 실행시키고 싶다면?
- 목표 : 유저가 클릭을 했다는 사실을 자바스크립트에서 catch해야 함
- 유저가 미리 행동하기 전에, 미리 요소에 이벤트를 받을 수 있도록 수신기 등록 필요
- EventTarget 객체
- 이벤트의 대상이 되는 객체(document, window, ...)가 EventTarget 객체를 구현
- 이벤트를 수신할 수 있는 수신기를 가질 수 있음 (listener)
- 이벤트 유형
- 유저와의 상호작용, 기본 환경 상태의 변화, ...
- click, focus(input), blur(input), ...
addEventListener
- Node.addEventListener(이벤트 유형, 콜백함수)
- 요소를 생성할 때, 이벤트 리스너도 함께 등록
$sectionHistory.addEventListener("click", function(event) {
const element = event.target;
if(!element.className.includes("delete-button")) return;
const { dateid, itemin } = element.dataset;
const isSuccess = removeHistory(dateid, itemid);
if(!isSuccess) {
alert("소비내역 삭제에 실패했습니다.");
return;
}
reRender();
});
3) 서버 간 통신
서버와의 통신
- 데이터 조작을 위해 클라이언트와 서버와의 통신이 필요
- 서버 통신에는 물리적인 시간 지연이 발생
- 요청과 동시에 바로 처리 불가능
- 요청 이후 응답이 오기까지 기다렸다가, 응답 신호를 받아야 함
- 자바스크립트는 이러한 상황에 필요한 처리기가 필요
- 콜백 패턴
- Promise 객체
- async - await
Promise
- 미래의 어떤 시점에 결과를 제공하겠다는 약속을 의미하는 이름의 Promise 객체를 제공
- Promise 객체의 3가지 상태
- 대기 pending : 수행 중..
- 이행 fulfilled : 수행이 성공적으로 완료
- 거부 rejefted : 수행 실패
- 메서드 :
- then : fulfilled 일 경우
- catch : reject 일 경우
const promise = new Promise((resolve, reject) => {
try {
resolve('result');
} catch (err) {
reject('failure reason');
}
});
promise
.then(() => { ... })
.catch(() => { ... })
동기와 비동기
- 동기 : Synchronous
- 직렬적으로 작업을 수행하는 방식
- 요청 이후, 응답을 받아야지 다음 동작이 이루어지는 방식
- 비동기 : Asynchronous
- 병렬적으로 작업을 수행하는 방식
- 요청 이후, 응답수락 여부와는 상관없이 다음 작업이 동작하는 방식
async - await
- 비동기 처리 패턴 중 하나
- Promise의 단점을 보완하고 가독성을 높여줌
- 함수에 aysnc 키워드를 붙여, Promise 인스턴스를 반환하도록 함
- await를 Promise 인스턴스 앞에 추가하여, 성공처리 이후에 다음 함수 명령문이 실행되도록 함
const promise = new Promise((resolve, reject) => {
try {
resolve('resolve');
} catch (err) {
reject('failure reason');
}
});
const foo = aysnc () => {
try {
const result = await promise;
console.log(result);
return result;
} catch (err) {
console.error(err);
}
};
[2] 프로젝트 셋팅하기
1. 프로젝트 셋팅
웹프론트엔드 개발자의 책임
- 구현) 빠르고 생산적으로 기능을 구현
- 자동화) 개발 속도를 낮춘다면 빠르게 개발할 수 있도록 자동화 및 개편
- 책임 분담) 다른 개발 소스에 활용
- 적용) 빠르게 서비스에 적용
- 지속적인 통합 배포 : 개발 단계 → 배포 단계
- 개발 단계 : 개발을 생산적으로 빠르게 진행해야 함
- 배포 단계 : 파일을 서버에 업로드
- 사이클이 반복적, 최적화된 상태로 이루어질 수 있도록 셋팅이 필요

npm
- 다른 이가 만든 코드 패키지를 사용하여, 프로젝트 작업의 시간을 단축할 수 있음
- 노드 패키지 매니저
- node.js의 패키지 관리자
- 모듈 설치를 관리해주는 역할을 함
스타일링용 pre-processor
- Sass : CSS의 전처리기
- CSS의 한계와 단점을 보완
- 가독성을 높이고, 코드의 재사용에 유리한 CSS를 생성하기 위한 확장
번들러
- html, css, javascript 파일들
- 개발 편의와 브라우저에서의 최적화 코드 간 형태 차이
- 개발 편의 : 가독성, 프레임워크 및 라이브러리 사용, ...
- 브라우저 최적화 : 용량 최적화, 캐싱, 리소스 최적화, 버전 대응, ...
- 작업된 코드를 브라우저에 최적화되도록 정리하는 중간 처리기가 필요
- 번들러 : 의존성 있는 모듈 코드를 하나의 파일로 만들어주는 도구
- 대표적인 번들러 :
- webpack, vite, parcel, ...
2. 협업을 위한 셋팅
함께 작업 시
- 협업 시 작업 생산성 올리기
- 코드를 빠르게 이해하여, 정확히 수정할 수 있도록 하기
git
- 여러 명의 유저 간에 파일들의 작업을 조율하기 위한 버전관리 시스템
- branch와 merge
- branch) 유저간의 작업이 독립적으로 분기되어 작업됨과 동시에
- merge) 작업이 완료가 되면 코드를 병합하는 과정이 필요
- branch는 라벨링을 통해 관리될 수 있음
- 주요 branch가 존재
- 작업을 위해 특정 시점에 주요 branch에서 신규 branch를 생성
- git checkout -b "브랜치 이름"
- 조작 방법
- 터미널 cli
- GUI로 사용가능 : 소스트리, ...
- 파일 수정이 이루어지면, 해당 시점의 수정사항을 스냅샷하여 저장하기 위해(git add 파일) 메세지와 함께 로그를 남김 (git commit -m "메시지")
원격 저장소 - Github
- 파일 관리 환경
- 내 컴퓨터에서 관리 : local
- 원격저장소에서 관리 : remote
- 깃 저장소 호스팅 웹서비스
- 커밋한 내역을 원격 저장소에 올림
- git remote add {{ 원격 이름 }} {{ 원격 저장소 url }}
- git push {{ 원격 이름 }} 브랜치명
읽기 좋은 코드
- 함께 협업하며 코드를 작성하기 때문에
-> 읽기 좋은 문서의 형태로 유지
-> 다름 사람이 구현한 코드여도 빠르게 이해할 수 있도록 함
- 코드의 구조를 빠르게 파악하도록 돕기
- 관심사를 분리하기 (목표 : 테스터블한 모듈)
- 코드 생산을 줄이기
- 코드의 재사용성을 높이기
- 레커시 코드가 많지 않도록 꾸준히 관리
- 코드를 통일화하여 가독성 올리기
- 코드 포맷팅 : 일관된 코드스타일 유지
- 네이밍 규칙
- 컨텍스트 이해를 빠르게 돕기
- 주석