Upgrade to Pro — share decks privately, control downloads, hide ads and more …

복잡한 상태관리도구 Svelte스럽게 만들기

kakao
December 08, 2022

복잡한 상태관리도구 Svelte스럽게 만들기

#Svelte #RxJS #상태관리 #함수형프로그래밍

Svelte에 맞는 상태관리 라이브러리를 만들기 위해 각종 상태관리 도구들을 이해하고 공부하면서
알게 된 반응형 프로그래밍과 함수형 사고 그리고 MVI 아키텍쳐에 대해 알아봅니다.

Svelte에 Rx 적용을 하고 FLUX 아키텍쳐를 재해석하여 만들어낸 상태관리도구를 소개합니다. 또한 이 라이브러리를 통해 개발하면서 마주쳤던 UI 프로그래밍을 힘들게 하는 비동기 처리, 중첩된 거대한 객체를 다루는 문제들을 어떻게 해결을 했는지 알려드립니다. 실제 파트원들도 사용해보면서 느낀 점 그리고 앞으로 어떤식으로 발전을 해나야가야할지 느꼈던 인사이트와 로드맵을 공유하고자 합니다.

발표자 : teo.yu
카카오엔터프라이즈 시니어 프론트엔드 개발자 테오입니다. 카카오워크의 캘린더 서비스를 개발하고 있습니다.

kakao

December 08, 2022
Tweet

More Decks by kakao

Other Decks in Programming

Transcript

  1. Copyright 2022. Kakao Corp. All rights reserved. Redistribution or public

    display is not permitted without written permission from Kakao. 복잡한 상태관리도구 Svelte스럽게 만들기 유용태 teo.yu 카카오 엔터프라이즈 if(kakao)2022 Svelte + Rx를 이용한 Write less Code 상태관리 라이브러리 개발 이야기
  2. 상태관리 라이브러리를 만들게 된 배경 Svelte에 Rx 더하기 프론트엔드 아키텍쳐

    다시 써보기 실전과 부딪히며 라이브러리 확장/개선하기 카카오워크웹파트 사용후기 배운 점, 그리고 향후 로드맵
  3. 전역 상태 / 공유 상태 제공 Props Drill Problem 이슈

    해결 뷰 로직과 비즈니스 로직의 분리 우리가 상태관리를 사용하는 이유 👌
  4. 전역 상태 / 공유 상태 제공 Props Drill Problem 이슈

    해결 뷰 로직과 비즈니스 로직의 분리 상태가 언제 어떻게 왜 변화하였는지 추적하기 상태 변화를 예측 가능하게 프로그래밍 하기 디버깅을 용이하게 하기 우리가 상태관리를 사용하는 이유 🤔
  5. - 전역상태와 Props Drill Problem은 해결 되었지만... - 여전히 컴포넌트

    간 복잡하게 얽히는 데이터 흐름과 구조 - 데이터의 변화 추적와 디버깅이 점점 더 힘들어진다. - 이걸 전역 스토어로만 해결하는게 맞을까? - 전역 스토어는 전역 변수랑 뭐가 다르지? - 컴포넌트가 비즈니스 로직에 의존성이 있어도 되는 걸까? - 뷰 로직과 비즈니스 로직의 분리의 경계란? - 좋은 구조란 무엇인가? - 이런 고민을 한다는 것 부터가 일단 지금이 좋은게 아니라는 거겠지? 복잡한 상태관리에 대한 고민과 문제들 😵💫
  6. "Pet Hunt 선배님. 지금이 바로 그때 인것 같아요..." ೒۟झо ೙ਃೞѱ

    ؼ ٸݶ ঌѱ ؼ ѩפ׮. ೙ਃೠ૑ ഛपೞ૑ ঋਵݶ ೙ਃೞ૑ ঋणפ׮. ӒܻҊ Ӓ ೙ਃೡ ٸۄח Ѫ੉ ޥ૑ ঌѱ غ঻णפ׮
  7. Atomic 상태관리 - 쉽고 단순하지만 복잡도가 올라갈수록 관리가 어려움. 서버

    기반 상태관리 - 대부분은 좋으나 특이 케이스 대응이 어려움 더 나은 Svelte용 상태관리 라이브러리를 만들자 '내가 하는 개발은 엔터프라이즈 FE, 앞으로 점점 더 복잡해질 수 밖에 없다.' => 쉽고 편리함 보다 복잡하더라도 추적과 디버깅에 용이한 더 체계적인 상태관리 라이브러리가 필요하다!
  8. Rx란? 반응형 프로그래밍을 할 수 있도록 해주는 API RxJS is

    a library for reactive programming using Observables, to make it easier to compose asynchronous or callback - based code.
  9. Rx는 시간도 선언적으로 다룰 수 있게 해준다. 트리플 클릭 구현하기

    7초동안 응답이 없으면 에러처리 에러가 발생하면 3초 후 다시 시도 3번 실패하면 에러 🤕 setTimeout? callback? promise?
  10. Rx에 있는 유용한 Operator들 - map / fi lter /

    take - distinctUntilChanaged - bufferCount - debounce - throttle - retry - timeout - mergeMap / switchMap / exhaustMap / concatMap - 그밖에도 정말 좋은 Operator들이 있어요! 🤩
  11. 그렇지만 Rx도 굉장히 코드가 장황합니다. Svelte와 오리지널 Rx는 물론 궁합이

    좋지만 Svelte Store와 결합하여 훨씬 단순한 Rx를 만들고 싶었어요.
  12. Svelte와 Rx의 퓨전! RxJS Svelte Store 복잡하지만 풍부한 기능 단순하지만

    단순한 기능 svelte와 일부만 연동 svelte와 완전히 연동 New Rx! 단순하지만 풍부한 기능 svelte와 완전히 연동 +auto - unsubscribe +dot chain 지원 +Typescript 지원
  13. MVI 아키텍쳐 (Model - View - Intent) - Unidirectional cycle

    of data - Non - blocking - Immutable state -> Functional Paradigm Model() User() View() Intent()
  14. User(View(Model(Intent(User(screen)))) screen -> event -> action -> state -> screen

    type User = (screen) => event type Intent = (event) => action type Model = (action) => state type View = (state) => screen Model(action) User(screen) View(state) Intent(event) action event state screen
  15. MVI 아키텍쳐 관점에서 Svelte + Redux 바라보기 Component Action Reducer

    Store Model(action) Reducer User(screen) View(state) Component Intent(event) Event Handler on(action) event store.update() screen dispatch(action) store.subscribe()
  16. ₩ Action Model 아키텍쳐 다시 써보기 Reducer Store dispatch on

    writeTo subscribe Intent View Component State Management
  17. 카운터 샘플 코드 1. 컴포넌트와 상태관리 코드를 완전히 분리할 수

    있어 화면 변화에 유연해집니다. 또한 프로그래밍을 사용자의 행동을 중심으로 생각할 수 있도록 해줍니다.
  18. 카운터 샘플 코드 3. 그리고 언제, 왜 데이터가 어떻게 변했는지

    추적이 가능합니다. #0 _증가, count: 0 -> 1 #1 _증가, count: 1 -> 2 #2 _감소, count: 2 -> 1 #3 _초기화, count: 1 -> 0 #4 _증가, count: 0 -> 1
  19. 카운터 샘플 코드 서비스가 복잡해지고 관리해야 할 상태가 늘어나도 화면변화

    대응에 유연하고 상태변화 추적에 용이하며 디버깅하기 쉬운 개발을 할 수 있다.
  20. 전역 상태 / 공유 상태 제공 Props Drill Problem 이슈

    해결 뷰 로직과 비즈니스 로직의 분리 상태가 언제 어떻게 왜 변화하였는지 추적하기 상태 변화를 예측 가능하게 프로그래밍 하기 디버깅을 용이하게 하기 우리가 상태관리를 사용하는 이유 😎
  21. - 프로그램이 작성한 순서대로 동작하지 않는다 - 결과를 예측할 수가

    없고 성공과 실패, 로딩중과 캐시 등의 다양한 분기를 가진다. - 그렇지만 비동기 결과의 순서를 조정해야 할 필요가 생긴다. => 낮은 예측성, 강한 결합도를 가진 복잡한 코드 => 유연하지 못하고 디버깅이 어려운 코드 문제는... UI가 곧 비동기라는 것 비동기 프로그래밍이 어려운 이유 A B C D
  22. - 같은 구성이라도 Push의 관점으로 바라보면 작업이 간단해집니다. - 모듈

    내 역할만 수행하고 생성한 데이터와 제어권을 다른 모듈에게 위임하는 방식 - 하나의 거대한 관리자 모듈이 필요없기 때문에 모듈의 의존성이 낮고 간결해진다. 복잡한 비동기 Push 방식으로 풀어보자! A C D B
  23. Firebase를 연동하면서 배운 것들 - path를 이용한 중첩된 객체 다루기

    - path별로 Atom이 될 수 있다! - Array보다 key - value Object로 다루기 - Collection을 Object.values와 sort로 다룬다. -> path를 기반으로 하는 Reactive한 database API를 만들자.
  24. 언뜻 복잡해보이는 체계를 가지고 있으나 데이터가 한 방향으로 선형적으로 움직이고

    있기 때문에 Input - Ouput을 기반으로 어느 공정에서 어디를 수정해야하는 더 찾기가 쉬워졌습니다.
  25. Adorhable Store action() dispatch() on() reducer() story() database() query() type

    Collection createStore() SELECT() UPDATE() GET() DELETE()
  26. 좋았던 점 데이터를 다루는 흐름을 자연스럽게 이해할 수 있었다. 내가

    개발을 할 때 지금 어느 단계의 데이터를 어떻게 만들고 전달해야하는 지 알 수 있다. 자동으로 로깅이 되어 디버깅을 하기에 수월했다. 문제가 발생했을 때 언제 어떻게 데이터가 수정이 되었는지 알수 있어서 디버깅 하기에 좋았다. 복잡하게 생각하지 않을 수 있게 해줘서 좋았다. 이미 만들어진 체계 위에 새로운 기능을 확장하거나 수정하기에 용이했다.
  27. 배운 것 복잡함에는 이유가 있다. 개념은 복잡해도 문법은 단순하게 만들

    수 있다. 복잡한 구조도 단순한 관점으로 바라볼 수 있다. 체계가 곧 컨벤션이 될 수 있다. 계층을 더 잘게 만들어 둘 수록 복잡해지지만 더 단순하게 생각하게 만들어준다. 계층이 곧 컨벤션이 되고 이는 클린코드로 이어진다.
  28. 현재 개발하고 있는 것들 Devtools User Input Database LocalStorage, IndexedDB와

    같은 스토리지 기반 자동 연동 낙관적 업데이트를 위한 트랙잭션 API React에서도 쓸 수 있도록 Test Library와 TDD
  29. 전역 상태 / 공유 상태 제공 Props Drill Problem 이슈

    해결 뷰 로직과 비즈니스 로직의 분리 상태가 언제 어떻게 왜 변화하였는지 추적하기 상태 변화를 예측 가능하게 프로그래밍 하기 디버깅을 용이하게 하기 ... Write less 하게 계속 만들어 가 보겠습니다!! 끝으로... 상태관리를 만들고 싶었던 이유 😎