반응형

 

(이 글은 이전 블로그에서 백업한 글을 불러서 가공한 글입니다. 원글의 작성 시기는 대략 2020년 5월쯤이고, 이 프로젝트를 진행한 시기는 2020년 4월 약 2주간입니다.)

 

프로젝트의 시작 계기

 

to do list를 만들어보고자 처음 시도했을 때에는 그저 바닐라 자바스크립트를 연습을 하는 것이 목적이었습니다. 하나의 프로젝트가 될 거라고 생각하지 않았죠. 하지만 일이 진행될수록 점점 불만이 생겼고 그것을 개선하고자 하는 욕구가 커졌죠. "할 일을 적는데 왜 날짜랑 시간이 없어?", "CRUD를 하는데 저장 데이터가 없어? node.js와 json을 써야겠네", "앱을 쓸 때마다 로컬 서버를 켜야 하나? 그냥 exe포맷의 데스크톱 앱으로 만들어보고 싶다." 그래서 자바스크립트로 데스크톱 앱을 만드는 방법을 찾아봤습니다. 노드 웹킷도 있고 다른 것들도 있지만 electron이 가장 많이 사용되는 것으로 보였고 참조할 자료가 많았기 때문에 electron을 사용해보기로 합니다.

 

사용 기술 : html, css, javascript ES6, node.js, electron


그래서 electron으로 만든 투두 리스트 앱이 어떻게 생겼는지 간단히 소개를 하고, 느낀 점들을 간단하게 적어볼 생각입니다.

 

앱의 기능

 

- 날짜 별로 리스트를 분리하여할 일을 추가, 수정, 삭제하고 읽어올 수 있습니다.

- 마친 일은 체크표시를 할 수 있습니다.

- 이 모든 데이터는 하나의 json파일에 저장됩니다.

- 전체 목표 달성률, 최근 30일간 목표달성률, 최근 7일간 목표 달성률을 보여줍니다.

- 달력과 체크 색상을 각각 4가지씩 제작하였고 사용자 입맛대로 골라서 적용할 수 있습니다.

- 모든 CRUD 조작에 대하여 UNDO/REDO 기능을 수행할 수 있습니다.

 

 

완성품은 이렇게 생겼습니다.

 

 

 

반응형

 

 

시나리오

 

  • app 실행 시

main.js 실행 → index.html 실행 → myCalendar.js 실행 → environment.js 실행 (node.js 내장 모듈, 앱 설치경로 얻기) → fileController.js 실행 (CRUD, JSON파일 조작, 메멘토 패턴) -> memento.js 실행 -> renderer.js 실행 (color설정 조작, 메뉴 구현) → mainController.js (사용자와 상호작용하는 부분)

 

  • 새로운 plan 추가 시

create ( 선택된 날짜와 입력된 plan을 todolist.data 객체에 저장 → undoStack에 push → wirte json )  read ( 달력에서 현재 선택된 날짜의 모든 리스트 읽어서 출력하기 목표 달성률 출력하기 )

 

  • plan 혹은 check 수정 시 (change 이벤트)

update ( 값이 변한 타깃의 tr태그의 class명 받아오기  → 현재 선택된 날짜와 class명을 통해 todolist.data객체에서 해당 plan 혹은 check값에 접근 및 변경 → undoStack에 push → write json )

 

  • plan 삭제 시 (click 이벤트)

delete ( 타깃의 tr태그의 class명 받아오기 → undoStack에 push todolist.data 객체에서 number(key)에 접근하여 delete → write json ) -> read

 

  • remove all list (메뉴)

delAll (todolist.json을 삭제하고 빈객체로 다시 만들기) -> win.reload()

 

  • color 변경 (메뉴)

colorSetting ( color값 변경 → write json ) -> read

 

  • undo/redo (메뉴)

restoreUndoMemento ( RedoStack에 push → undo 실행 ) → read

restoreRedoMemento ( UndoStack에 push → redo 실행 ) → read

 

 

배워서 사용한 스킬들

 

1. 모듈 패턴

 

이 앱은 크게 보면 두 가지 기능으로 나눌 수 있습니다. 하나는 달력의 조작, 다른 하나는 to do list의 CRUD조작입니다.

CRUD는 이 앱에 특화되게 코드를 작성해야 하는 부분이지만 달력은 한번 만든 코드를 다른 곳에서도 사용할 수 있어야 한다는 생각이 들었습니다. 따라서 즉시 실행 함수와 클로저를 이용한 모듈 패턴을 적용하여 myCalendar라는 모듈을 만들었습니다.

 

 

2. 성능개선

 

가벼운 프로젝트기에 성능 문제를 크게 신경 쓰면서 만들진 않았으나 혹시 데이터가 1년, 2년 치가 쌓인다면 for문 실행시간이 오래 걸리지 않을까 하는 염려가 생겼습니다. 특히 신경 쓰인 부분은 리스트를 read 할 때마다 '목표 달성률'을 계산하기 위해 todolist.data라는 전역 객체를 for in 문으로 돌리는 부분이었습니다.

실행시간 측정을 위해 dev라는 모듈을 만들어 코드 실행 시각과 끝나는 시각을 구해 그 차이를 빼는 방식을 사용했고,

데이터가 1년 이상 쌓여도 for문 실행시간은 이전과 똑같이 1ms 정도로 별 차이가 없다는 것을 확인하였습니다.

 

다만, '최근 30일 목표 달성률'을 구하기 위해 최근 30일 배열을 만드는 과정에서 new Date()을 30번 사용하는데 이것이 3~4ms로 시간이 오래 걸린다는 것을 확인하였고 이 과정을 되도록 생략하기 위해 캐시 객체를 만들어 캐시에 저장하여 꺼내 쓰는 방법을 사용해서 실행시간의 3~4ms를 세이브하였습니다.

 

 

3. 메멘토 패턴

 

CRUD의 Undo / Redo 기능을 만들기 위해 메멘토 패턴을 적용했습니다. 사실 이것은 앱을 다 만들고 사용해보면서 느낀 것인데 한번 삭제한 리스트를 다시 복구할 수 없다는 것이 너무 불편하여 적용해야겠다는 생각을 했습니다. FileController와 Memento라는 두 개의 class를 만들어 FileController.memento를 new Memento()로 인스턴스 하였고 memento의 undoStack과 redoStack에 CRUD 실행 메서드와 변동사항을 저장하여 사용하도록 했습니다. FileController는 originator 객체를 사용하고, 그를 조작하고, json파일도 조작하는 기능을 담당하도록 했습니다.

 

 

수정의 역사

 

주로 유지보수를 위해 코드를 개선하는 작업을 진행했고, json 객체의 구조를 변환하는 작업을 했습니다. 또한 새 기능을 위해 디자인 패턴을 공부하고 도입하기도 했습니다.

 

1차 개선은 유지보수를 위해 중복을 제거하는 작업이었습니다. 중복되는 코드는 최대한 함수로 만들어 호출하는 방법으로 제거했습니다.

 

2차 개선은 복잡한 json 디렉터리 구조를 하나의 객체로 변환한 것입니다.

기존의 방법은 날짜별로 폴더를 동적으로 만들어 각각의 to do 마다 json파일을 생성하고 수정하고 삭제하는 방법으로 하였습니다. 근데 이것은 너무 json파일을 남발한다는 문제도 있지만 fs모듈의 잦은 사용과 잦은 json의 string변환과 파싱으로 코드가 복잡해지고 가독성이 떨어진다는 문제도 있었습니다. 따라서 to do list의 날짜별 데이터를 모두 todolist.data라는 한 객체에 담아 하나의 json파일로 관리하는 방식으로 바꾸었습니다. 이렇게 함으로써 코드도 훨씬 간결해지고 객체로 관리하니 더 직관적으로 코드를 만들 수 있게 되었습니다. 또한 fs모듈을 이용한 json의 읽기는 앱 실행 시 1회만 사용하면 되고, 쓰기는 하나의 메서드의 호출만으로 가능하게 되었습니다.

 

<todolist.data 객체의 형식>

todolist.data = {
'20200411' : { 0 : {plan: plan, check: true},
	1: {plan: plan1, check: false},
	checkCount: 1},
'20200412' : ~~
}

 

 

3차 개선도 유지보수를 위한 리팩터링 작업이었습니다.

CRUD를 하면서 객체에 데이터를 쓰거나 수정하는 함수들을 상수 타입의 객체에 저장하여 필요한 곳에서 호출하여 쓰도록 하였습니다.

또 자주 접근하는 element는 querySelector로 접근하여 상수 타입의 전역 변수에 초기화하였습니다.

날짜를 8글자 (yyyymmdd)로 바꿔주는 코드도 비록 한 줄짜리이지만 함수로 만들어서 호출하여 사용하도록 하였습니다.

 

4차 개선에서는 메멘토 패턴과 ES6의 class문법을 공부하고 도입했습니다. 자세한 내용은 위에 이미 설명했으므로 생략하겠습니다.

 

 

한계점과 다음 목표

 

저는 자바스크립트 입문자의 입장에서 나름 노력을 한다고 해봤지만 작업 도중에 내가 만든 코드가 좋은 코드인지 나쁜 코드인지 확신이 서지 않았습니다. 내 코드가 어느 수준인지 확신이 서지 않는다는 것은 그만큼 자바스크립트에 대한 공부가 많이 부족하다는 증거라고 생각합니다. 그래서 자바스크립트의 공부가 갈 길이 정말 멀다는 것을 느꼈습니다.

다음으로 공부할 프레임워크는 react로 정했습니다. react를 공부하고 혹시 react native까지 하게 되면 지금 만든 앱에 기능을 좀 더 보완해서 안드로이드나 IOS용 앱을 출시하는 것도 좋을 것 같다는 생각이 듭니다.

 

혼자서 앱을 계속 쓰고 있는데 일단 불편한 점이 몇 가지 있습니다. 목록을 드래그해서 옮기는 기능이 있으면 더 좋을 거 같고, 키보드 방향키로 focusing 된 목록을 이동할 수 있으면 훨씬 편리해질 것 같습니다.

 

 

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기