FE Conf 2019 참관기
FE CONF 2019 를 다녀오고 이를 정리해보고자 한다.
헌집줄게, 새집다오 (리액트 프로젝트 구조 조정)
뱅크샐러드에서 기존 구조에서 현 구조로 변경 하기까지의 경험을 공유해 주셨다.
기존 구조는 페이지별로 독립적인 도메인을 중심으로 설계가 되었다고 한다.
각각의 페이지들은 역할별로 Presentation (사용자 로직), Data (Api Data), Domain (useCase), Entity (개념) 으로 추상화된 Layer 로 나누어져 관리되고 있었다.
이 Layer 들은 Context 라는 하나 Class 에서 view, data, core 등이 관리되고 있었는데, 코드의 복잡성과 중복 작성이 증가하게 되었고, 변경 하기가 쉽지 않다고 한다.
특히나, 모바일 웹뷰의 작업들로 화면들이 점점 더 늘어나게 되어, 처리해야하는 entity 는 점점 늘어나게 되었고, core 부분에서도 구현부와 정의부 로 각각의 파일로 나누어져 있어 참조해야할 파일이 많아지고, View 와 Service 간에 의존도가 높고, 어디에서 쓰이는지 관리가 안되다 보니, 나중에는 삭제할 수 있는지 없는지 판단이 안되기 시작해서, 구조 변경을 결정하게 되었다고 한다.
하지만 기존 로직 전체를 수정하는 것은 공수가 너무 많이 들어서, 신규 서비스 부터 구조를 분리해 내기 시작했는데,
- 정의와 구현을 같은 곳에 두고 정의와 함께 의존성을 주입하도록 수정하였다.
- 수정이 용의하도록 Redux 와 Redux-Observable 을 적용하여, View 와 Data 분리 하였다.
또한, Redux 로 작업하다보니, 하나하나 action 을 정의해주어야 했고, 이를 위해서 반복적으로 적어야 하는 코드가 너무 많아 졌는데, 이를 ActionHelper 라는 모듈을 만들어서, 반복작업을 줄였다고 한다.
100점 인 구조 찾아 적용하기 보다는 여러 구조를 실험 및 적용을 하는 방법으로 최적의 설계를 찾고 있는데, 이를 위해 sample project 를 생성하고, 설계한 구조를 빠르게 적용하고, 검증한 후 이를 scaffolding 도구로 만들어서 빠르게 적용 하신다고 한다.
이런 관점으로 구조를 만들수도 있겠구나 라는 것을 배울 수 있어서 재미 있는 세션이였다.
비동기를 우아하게 처리하기 위하 Observable
토스에서 Observable 에 대해서 설명해 주셨다.
웹에는 여러가지 비동기 처리가 존재하는데, Promise 가 이러한 비동기 처리를 도와주지만, Promise 는 중간에 취소가 불가능하고, 단일 값만이 처리가 가능하다고 한다.
예를 들어 어떤 특정 입력후, 네트워크로 값을 가져와야하는데, 만약 중간에 값을 바꾸게되더라도, 이전에 요청한 네트워크의 요청은 계속 진행되게 되어 바꾸어 요청한 값과 이전 요청한 값이 올바르지 않게 나오게 된다.
이를 쉽게 해결할 수 있는 방법으로 비동기 처리를 도와줄 Observable spec 이 Stage 1 에 Draft 되었다.
Observable 은 비동기로 발생하는 여러 데이터를 다루는 인터페이스로, 비동기 요청의 취소가 가능하고, 비동기 흐름을 쉽게 읽을 수 있게 도와준다.
Observable 은 next, error, complete 을 가질 수 있고, 이를 subscribe 로 구독할 수 있고 unsubscribe 로 구독을 취소할 수 있다.
Observable 은 함수 Composition 나 Chainable 형태도로 작성이 가능한데, 이렇게 훌륭한 Observable 은 현재는 draft 상태라서 쓸수가 없지만, 우리에게는 RxJS 가 있다.
RxJS 에서는 Observable 이라는 구현체를 제공하고, Composition 및 생성 유틸리티 제공 operator (Observable 재사용) 이 가능하다.
RxJS 6 부터는 Piping 이 추가되었는데, 그 이유는 prototype 에 operator 을 계속해서 확장 하게되면 Global 에서의 사용 이나 Tree shaking 이 힘들다고 한다.
Reactive Programming 에서 Event Stream 을 표현하는 방법중에 marble diagrams 이 있다. 이를 이용하면 흐름을 쉽게 표현이 가능하다.
Web 에서는 이러한 Observable 이 유용한데, 일반적으로 사용하는 pull 이벤트 형태에서는, 외부에 명령하여 응답을 받고 처리한다.
하지만 Web 에서 사용하는 이벤트는 언제 사용자 입력이 들어올지 모르는 경우가 많다.
때문에, Observable 에서 사용하는 push 이벤트 형태는, 외부에서 요청이 오면, 그때마다 반응하여 처리한다.
이러한 subscribe 방식은 마우스, 키보드 같이 언제 사용자 입력이 올지 모르는, 이벤트를 처리하기에 Observable 이 좋은 선택이 될수 있다.
개발에 은총알이 없는 것처럼 Observable 은 높은 러닝 커브 와 디버깅이 어려운 점 등 단점도 충분이 있다.
하지만 그럼에도 불구하고 Reactive Programming 은 매우 훌륭한 선택지이다.
RxJS 는 매번 배울 때마다 새롭고, 적용할 때마다 신나는 작업인것 같다.
Angular + ionic 으로 멀티플랫폼 PWA 개발하기
Petner 에서 혼자서 iOS, Android, Web 을 개발 하시면서 겪으셨던, 경험을 공유해 주셨다.
서비스의 사용자 대부분이 모바일 사용자 였기 때문에, 모바일 앱을 만들었어야 했는데, 개발자가 자기 혼자 뿐이 셨다고 한다. 하여 빠르게 만들 수 있는 멀티 플랫폼 프레임워크를 선택 하여야만 했는데, Ionic 으로 만들까, ReactNative 로 만들까 고민을 하셨다고 한다.
성능 상으로는 ReactNative 가 훨씬 우수 했지만, ReactNative 로 개발하려면 모바일 환경을 어느정도 알아야 했고, Ionic 은 이미 써본 경험도 있고, 웹으로 개발하는 방식이 편했으며, PWA 를 지원하는 등의 이유로 Ionic 을 선택 하셨다고 한다.
프레임워크는 당시에 Ionic3 이 Angular 만을 지원했기 때문에 Angular 를 선택하셨는데, Ionic4 부터는 Web Component 를 지원하기 시작해서 이를 적용하셨다고 한다.
Web Component 는 Style 의 커스텀화가 힘들었고, SSR 을 지원하지 않아서, ion-tabs, ion-modal 같은 네비게이션이 들어간 Web Component 들은 그대로 쓰고, atomic한 UI 컴포넌트들은 직접 만드셨다고 한다.
Angular 의 @NgMoudle, @Pipe, @Directive, @Injectable 같은 개념을 익히는 것은 어려웠지만, 익숙해지니 사용하기 편리했고, PWA 를 구현하는데, ng add @angular/pwa 면 충분했기 때문에 PWA 적용도 크게 어렵지 않았다고 한다.
Mobile App 개발하는데 있어서, Web 환경은 매우 매력적인 도구 인것 같다. 모바일 환경을 이해하는 것이 앞으로 웹개발에도 도움이 되지않을까 생각해본다.
프론트엔드에서의 마이크로 서비스 아키텍처
Erion 에서 web 에서의 MSA 를 설명해주셨다.
WebRTC 기반의 실시간 교육 서비스를 개발하고 계시는데, 클라이언트의 기능이 크기가 점점 커지다보니, 한 기능에서 예측되지 않는 오류로 인해 웹페이지가 그대로 죽어버리는 문제가 발생했다고 한다.
유료 서비스를 제공하는 입장에서는 매우 크리티컬 했는데, 점점 더 개발과 배포에 소극적으로 변하는 팀이 되어 갔다고 한다.
그래서 각 기능 간 의존성을 없애면, 오류를 줄이고 더 빠르게 부담없이 개발할 수 있지 않을까 라는 생각을 하시게 되었다.
의존성을 없애기 위해, 각각의 기능을 완전히 분리시키고, 각각의 Service 간 데이터 교환 체계를 어떻게 구축 하느냐 를 더 고민 하시게 되었다고 한다.
이러한 의존성을 해결하기 위해 iframe 으로 각각의 기능별로 따로 동작시키고, Service 간 데이터 교환 하기 위해 postMessage 의 규격을 정하기로 하였다고 한다.
데이터 교환 체계는
- Request — Response
- Action — Reaction
- One-way Binding
- Event
로 구성 하였는데, 각각의 메시지에 Unique 한 id 를 부여하고, 각각의 교환 체계에 따라 데이터 통신을 이루어지게 하셨다.
이 Message Protocol 은 Context 영역 (id, createAt, serviceInstanceId, userId) 와 Content 영역 (eventName, body) 로 구성하였다.
이렇게 WebApp 을 iframe 으로 구분하여 관리하게 되니, 기능들 사이의 의존성을 최소화하게 되었고, 기능에서 오류가 나더라도 해당 iframe 만 장애가 생기기 때문에, 전체 앱에 영향이 없게 되고, 테스트와 안정성, 서비스 개발 속도에 많은 장점이 있으셨다고 한다.
하지만 iframe 는 다른 여러 웹페이지들이 하나의 브라우저 탭의 single tread 로 동작하게 되니, 렌더링 성능에, 많은 하락이 있으셨는데, 크롬에서는 업데이트후 괜찮아져서 주 브라우저를 크롬으로 쓰고 있으시며, 성능 하락에도 불구하고, 더 큰 장점들이 있기 때문에 아직까지는 괜찮다고신다.
웹에서의 MSA 접근은 생각보다 흥미 있었는데, 문제를 해결하는 관점에서 운영적 해결 방법에 대해서 배울 수 있어서 매우 흥미로웠다.
3달간 Github 스타 3K 받은 Scence.js Moveable 오픈 소스 개발기
Naver 에서 Scence.js 와 moveable 을 개발하셨던 경험을 공유해 주셨다.
애니메이션을 Javascript 로 만들고 싶었고, 원하는 도구가 없으셔서, 직접 만드셨다고 한다.
CSS Animation 으로 구현하면 % 값이 필요했지만, 정확한 제어를 위해서 초 로 관리해야 했고, 동시제어 가 가능하며, Javascript 나 CSS 에서도 똑같은 재생방법을 가지고, CSS 를 Javascript 에서 더 쉽게 쓸 수 있는 방법을 고민하셨다고 한다.
제일 중요하게 생각하신건 사용하기 쉬워야 한다는 점인데, method 의 형태를 여러가지로 실험 하시다가 parameter 를 String 으로 전달하고 이를 Parsing 하는것이 사용성에서 쉬우셨다고 한다.
작업이 어느정도 진행되고, 이를 홍보하기 위해서, Scence.js API 문서를 열심히 정리하고, 사람들이 바로 볼수 있는 데모를 열심히 만드셨다고 한다. 이런 문서와 데모들이 잘 작성이 되어있어야, 개발자가 의도한 사용성을 쉽게 설명할 수 있기 때문이라고 한다. 그리고 이를 각 커뮤니티 사이트에 업로드 하였는데, 꽤나 반응이 좋아서 만족스러우셨다고 한다.
그리고 이렇게 만든 Scence 를 가지고 에디터를 개발해보기 시작 하셨는데, 각 Element 들의 조작이 어려워서 moveable 라는 툴을 만드셨다고 한다.
Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable, Groupable, Snappable 이 가능한 툴인데, 이를 개발하기 위해서 transform 을 파고 드셨다고 한다.
움직임의 위치는 부모 transform 에 영향을 받기 때문에, 이를 계산해야 했고, Absolute Matrix 를 만들었는데, 이런 문제를 겪고있는 사람들이 많았고, 생각했던것보다 인기가 많이 좋았다고 한다.
moveable 많은 사람들이 사용할 수록 많은 이슈들이 등록 되었는데, 라이브러리 안에서만 해결할 수 있는지, 많이 사용할지, 그리고, 본인이 만들려는 에디터에서 쓸수 있는지 등의 조건을 가지고 이슈를 처리한다고 한다.
없어서 만들었고, 필요해서 만들었는데, 매우 즐거운 과정 이였다고 한다.
오픈소스를 공개하는 과정은 사용자들을 설득하는 과정 이며, 개발자들을 설득하기 위해서는 문서와 데모는 필수에 가깝다고 한다.
당연하게도 작업은 재미 있어야 동기도 생기고, 본인이 지치지 않고 꾸준히 할 수 있다고 한다.
이러한 경험은 어떠한 작업을 할때든 도움이 될것 같다. 많이 배웠고 크게 배웠던 세션이였다.
진정한 CI/CD 를 위한 E2E Test 시작하기
체커에서 E2E Test 환경을 세팅 하신 경험을 공유해 주셨다.
자동화된 테스트는 정말 중요하다. 하지만 일반적으로 회사에서는 테스트 비용을 낭비라고 생각하기 때문에, 테스트에 대한 비용 이나 일정을 최소화 하려고 한다.
하지만, 개발자 자체적으로 단위테스트를 작성하고, 개발 완료후 통합테스트를 하더라도, 각각의 기능들의 테스트는 완벽할 수 있지만, 전체적은 시스템이 원하는 형태로 동작 또는 이후 (기능추가) 에도 그렇게 동작 할지는 확신할 수 없다.
E2E (End-to-End) 테스트는 전체 시스템이 제대로 작동 하는지 확인 하기 위해서 최대한 테스트 시스템을 사용자 관점의 상황을 만들어, 배포 후 발생할 수 있는 에러를 사전에 발견하는 테스트 이다.
E2E 테스트는 코드를 테스트하는것이 아니기 때문에, 내부 구조가 바뀌더라도 테스트에는 영향을 받지 않는다.
하지만 테스트 작성에 들어가는 비용이 너무 많고, 테스트가 주는 피드백이 Detail 하지 않기 때문에 발생된 원인을 찾기 어렵다.
스타트업의 생존에 가장 필요한건 계속된 실험을 통한 개선 이지만, 제일 중요한건 제품의 안전성이다.
피드백을 빠르게 반영하고 실험 하기위해서, 지속적인 통합(Continuous Integration) / 지속적인 서비스 제공 (Continuous Delivery) 을 할 수 있는 환경이 꼭 필요 하셨고, TDD 도 한적 없고 QA 도 없어서, 모든 테스트를 작성할 수는 없어도, E2E 테스트는 꼭 작성 해야겠다 마음 먹으셨는데, 자동화 된 E2E Test를 통해 제품을 항상 배포 가능한 상태로 유지하고, E2E Test 를 통과한다면 배포 해버리자고 결심 하셨다고 한다.
E2E Test 를 적용하기 위해서 일단 Nightwatch / Cypress / TestCafe 를 비교하셨는데, 안정성이 부족하지만 다양한 브라우저를 지원하고 Node로 코드 작성해서 좋은 TestCafe 를 선택하셨다.
Repo 에 Pull Request 를 날리면 Webhook 으로 Test Runner Server 가 E2E Test를 시작하고, macOS / Windows / Linux 환경 에서 Test Runner Client 가 실제 테스트를 구동하고, 결과를 Test Runner Server 가 Pull Request 에 기록하는식의 프로세스를 만드셨는다.
이렇게 작업해두니 과감한 리팩토링이 가능했고, 빠른 피드백이 가능해서 버그를 빠르게 발견하는것이 가능했다고 한다.
테스트하는 와중 실제 DB 를 사용하면 정합성이 깨지니, Docker 를 이용해서 테스트 할때마다 테스트 DB 를 구축 하셔서 테스트를 하신다고한다.
하지만 이런 E2E 테스트는 유지비용이 많이 들었는데, UI는 변경 되었지만 E2E Test 코드를 변경하지 않아서 테스트가 마구 터지는 상황이 많이 벌어지거나, 빠른 배포를 위해 E2E Test 없이 테스터가 손으로 테스트 한 상태로 배포하는 경우가 많이 생기 셨다고 한다.
E2E Test를 계속 유지하기 위해 꾸준히 투자 해야하고, 중요성과 필요성을 팀과 경영진이 이해 해야 일정 관리나 추가 비용 처리가 쉬워졌으며, 일정을 산정할 때 E2E Test 작성을 포함해야 작업에 용의 하셨다고 한다.
이러한 경험은 E2E 테스트를 도입함에 있어서 많은 도움이 될것 같지만, 역시나 이러한 프로세스를 만들기 위해서는 팀단위의 많은 노력이 들어감은 분명한듯 하다.
Angular 는 사실 어렵지 않습니다
카카오에서 Angular 가 어렵다는 오해를 풀어주셨다.
- 언어와 프레임워크는 무관하다.
- Angular 가 알아야 할것이 많지만, 그것은 앱이 커지면, React 나 Vue 도 똑같다.
- 양방향은 옵션이고, 단방향이 기본이다.
- Angular 와 다른 프레임 워크와 속도와 메모리 양은 크게 다르지 않다.
- Angular 가 용량이 많긴 하지만 다른 프레임 워크와 크게 다르지 않다.
- Angular 는 꾸준히 쓰이고 있다.
- 버전이 너무 빨리 올라가는건 1년의 정기 버전업일 뿐이며, 하위 호환성은 유지한다.
- Typescript 는 모두 쓰고 있다.
- 옵저버블은 필수가 아니다. 반응형, 함수형 방법론일 뿐이다.
- Angular 는 웹 표준 준수를 매우 준수한다.
- 강력한 CLI를 제공해서 전세계 개발자가 동일한 환경을 쓴다.
- Angular 는 정말 방대한 가이드 문서를 가지고 있다.
- 종합 프레임워크로써 개발 방법 단일화, 이미 보장된 안정성 & 최적화가 가능하다.
- 안전 참조 연산자와 파이프 & 비동기 파이프 를 쓸 수 있다.
- 인터셉터 체인이 가능하다.
- LifeCycle Hook 자식 Cycle 까지 포함하여 매우 다양하다.
- 라우터 이벤트의 조작이 편리하다.
- 최신 트렌드를 가장 적극적으로 반영한다.
결론으로 뭐가 더 좋아요? 라고 물어본다면, 쓰고 싶은걸 써라.
프레임워크는 우리가 웹 개발을 더 잘하기위한 도구일 뿐이며, 역시 제일 중요한것은 기본기인것 같다. 프레임워크는 죄가 없다.
마무리
이번 FE CONF 는 주제가 다양해서 좋았던것 같다.
웹 개발의 성숙도가 증가함에 따라 여러 다양한 시각을 공유 받을 수 있었고, 다양하게 경험 했던 지식들을 공유 받을 수 있어서 매우 즐거웠다.
다음 FeConf 도 참여 할 수 있었으면 좋겠다.