(이 글은 2017년 12월 18일에 수정되었습니다.)

요즘 세상의 웹 프론트 엔드 개발이라는게 참 쉽지가 않습니다. 이미 해야할게 산더미같이 쌓여있는데 자꾸만 새로운게 나와서 개발자들을 혼란스럽게 하죠. 어떻게 보면 그만큼 프론트엔드가 다루어야할 영역이 늘어나고 있다는 것이니 관련 개발자들 입장에서는 참 흥분되는 시대이기도 합니다.

몇가지 프로젝를 진행하면서 느낀 것들이 참 많은데요. 그 중에서도 핵심적인 부분들을 이 글을 통해 한번 나누어 보고자 합니다.

#Front-End Stack

요즘처럼 프론트엔드가 뜨거운 시대에 자신에게 알맞은 스택을 선택하는 것은 꽤나 사람을 고민에 빠지게 하는 일입니다. 써보고 싶은게 참 많지만, 괜히 잘못 선택했다가 deprecated되는게 아닌지 걱정되기도 하구요. 무엇보다 자신의 프로젝트에 적합한 것이 무엇인지 명확하게 파악하기 쉽지 않을 때가 많죠.

Front-End(redux-observable의 로고가 참 오묘합니다.)

제가 가장 선호하는 메인 프론트엔드 라이브러리는 React입니다. React는 가볍고, Learning curve가 가파르며, 유연한 라이브러리로 알려져 있습니다. 더불어 역동적인 개발자 커뮤니티와 빠르게 성장하는 관련 기술들이 무궁무진한 가능성을 열어주고 있죠. 마지막까지 Angular2와 React를 놓고 고민했지만, 최종적으로 React를 선택한 것은 활발한 React 커뮤니티에 매력을 느꼈기 때문입니다.

1. React는 결코 가볍지 않다.

그러나 React는 Angular와는 달리, 혼자서 어플리케이션 전체를 관장하는 Framework가 아닙니다. Facebook의 공식 설명에 따르면, React는 UI를 만들기 위한 Javascript Library입니다.

개발과정에서 제가 절실히 느낀 것이 하나 있습니다. 그것은 React가 가볍다고 볼만한 라이브러리는 아니라는 것입니다. React만 떼어놓고 본다면 상대적으로 가볍다고 볼 수도 있습니다. 하지만 실제 개발과정에서는 어쩔 수 없이 이런 저런 것들(Redux, observable, React-Router 등등)이 필수적으로 붙게 됩니다.

React를 제대로 쓸려면 Flux구조로 전체 프론트엔드 아키텍쳐를 짜는 것이 적합하고, 그러면 Redux , Flux 혹은 MobX를 도입해야되는데, Component 혹은 Store의 상태 변화를 제대로 비교하기 위해 Immutable 라이브러리도 공부해야 하며, 앱이 커지면 Type Check를 위해 Flow 혹은 TypeScript를 고려해야 할 수도 있고, 라우팅을 해주기 위해 React-Router를 따로 붙여줘야하는데 V3도 있고 V4도 있는데 무엇을 써야하는지, 그런데 서버사이드 렌더링을 할 수 있다는데 그러면 어떻게 해줘야 하는건지……React를 제대로 쓴다는 것은 부가적인 모듈에 대한 끊임없는 학습을 요구합니다.

Typescript, Observable 등 많은 개념을 기본으로 포함하고 있는 Angular2에 대한 거부감 때문에 React를 선택하시는 분들이 있는데, 결국 개발을 하다보면 별반 차이가 없어진다는 것이 제 결론입니다. 곧 정식으로 출시될 React fiber에서는 더 많은 것들이 바뀌고 추가될 예정입니다. 리액트 자체는 앞으로도 계속 몸집을 불려나갈 가능성이 높습니다.

2. 매력적인 Flux 아키텍쳐, Redux는 최선의 선택인가?

일단 저는 Backbone 혹은 Angular를 사용한 MVC 구조의 개발에 익숙한 상태였습니다. 그러나 Flux 아키텍쳐로 개발을 시작한 후, 그 매력에 푹 빠져버리고 말았습니다.

Rethinking Web App Development at Facebook

먼저 Flux라는 이름을 유심히 들여다 봅시다. Flux는 “흐르는”, “흐름”이라는 뜻을 가지고 있는 라틴어 fluxusfluere에서 유래된 단어입니다.

“Flux: fluxus, fluere(흐르는, 흐름)”

기존의 MVC 방식이 중점을 두고 있는 것은 Model, View, Controller의 역할 배분과 이에 기반한 구조적 설계입니다. 그러나 Flux는 이벤트와 데이터의 흐름에 주목합니다. 이것은 앱 개발에 대한 사고의 전환을 요구합니다.

Flux는 Facebook의 MVC 방식에 대한 문제의식에서 시작되었습니다. Facebook의 타임라인, 개별 포스팅, 알림 등은 수없이 갱신되고 서로 영향을 주고 받습니다. 그것도 수없이 많은 사용자들이 서로 얽힌 상태로 말이죠. 이런 상황에서 데이터의 흐름이 꼬여버리고, 순간적으로 예측불가능한 상태에 빠진다면 그 파급효과는 한 사용자의 경험 내에서 뿐만 아니라, 그 사용자와 연결된 다른 사용자들에게까지 확장될 수 있습니다.

Flux는 이벤트와 데이터의 흐름을 아예 단방향으로 만들어버림으로써 이 문제를 해결했습니다. 또한 각 흐름에 순서를 부여함으로써, 전체 앱을 훨씬 더 통제가능하고 예측가능한 구조로 만들어줍니다.(Facebook의 공식 Flux 페이지에서 훨씬 자세한 설명을 볼 수 있습니다!)

Flux는 크게 Action, Dispatcher, Store, View 4가지 요소로 이루어져 있습니다. 일단 View는 MVC 구조의 View와 같이 UI/UX를 통해 조작되는 부분입니다. 문제는 나머지 부분입니다.

명확한 흐름의 Flux 아키텍쳐

한번 쉽게 설명을 해보겠습니다. Action은 일종의 ‘박스’입니다. 이 박스 안에는 앱 내의 조작, 혹은 데이터의 변화에 관련된 내용이 담겨 있습니다.(좋아요를 눌렀다거나, 혹은 서버로부터 새로운 데이터를 받아왔다거나 등등….)

그러나 박스를 포장하는 것만으로는 아무런 변화가 일어나지 않습니다. 박스가 준비되었으면 이제 박스를 택배회사를 통해 보내야 합니다. 이때, 택배회사에 해당하는 것이 바로 Dispatcher입니다.

Dispatcher는 Action을 받은 순서대로 늘어놓습니다. 박스는 보낸 순서대로 배송지에 도착해야 하기 때문이죠. 왜 이렇게 해야하나구요? 바로 Flux라는 운송법 때문입니다. Flux라는 운송법에는 먼저 보낸 택배가 먼저 배송지에 도착해야한다는 규제가 있습니다. 준법정신이 투철한 택배회사(Dispatcher)는 각 박스들이 언제나 보낸 순서대로 배송지에 도착하도록 관리합니다.

이제 택배(Action)가 택배회사(Dispatcher)를 통해 배송지(Store)에 전달되었습니다. 택배를 받은 사람은 택배를 뜯어서, 누구한테서 어떤 택배가 왔는지 확인합니다. 그리고 택배 안의 내용물을 보고 자신이 해야할 일을 합니다. (Store의 상태를 변경하고 View를 갱신)

모든 일을 처리하고 난 후, 택배를 받은 사람은 다시 창밖을 살펴보고 다음 택배가 있으면 박스를 뜯고 똑같은 작업을 반복합니다. 이것이 바로 Flux 아키텍처의 핵심입니다.

“Action = 박스, Dispatcher = 택배회사, Store = 배송지”

Redux는 가장 많이 쓰이는 Flux 아키텍쳐 구현체(이외에도 Flux, MobX등이 있습니다.)입니다. Flux의 개념에 충실하면서도 단일 스토어, 함수형 프로그래밍, 미들웨어 등의 개념을 도입하여 더욱 직관적인 프론트엔드 설계를 가능하게 합니다

다른 Flux 구현체들과 비교했을 때, Redux의 가장 큰 특징은 전체 앱을 하나의 스토어로 관리한다는 점입니다. 이는 앱을 한층 더 예측가능하게 만들고, 다수 스토어간의 충돌을 방지할 뿐만 아니라, 시간여행 디버깅을 가능하게 합니다.

무엇이든 장점이 있으면 단점이 있는 법이죠. Redux는 하나의 스토어로 모든 상태를 관리합니다. 이는 앱 전체의 흐름을 잘 통제할 수 있게 하지만, 반대로 대량의 Dispatch가 발생하는 상황에서 앱 전체의 병목 현상을 발생시킬 수도 있습니다.

React Cof 2017: Redux VS MobX(지금 이 순간에도 Redux와 MobX의 싸움은 계속되고 있습니다!)

Redux에서는 연쇄적으로 발생하는 수많은 Dispatch들을 관리할 방법이 마땅치 않습니다. 이를 해결하기 위해, Redux-thunk, Redux-saga 등의 미들웨어들이 거의 필수적으로 사용되죠. 저는 Redux-Observable을 사용하여 Ajax 요청과 Dispatcher들을 반응적으로 관리하고 있습니다.

MobX는 다수의 Store를 가질 수 있으며 Observable을 기본적으로 사용하고 있기 때문에, 상대적으로 유연하게 데이터 흐름을 관리할 수 있습니다. 특히 RxJS의 Observable 패턴을 좋아하시는 분들이라면, MobX는 Redux보다 더 나은 선택이 될 수 있습니다.

반면 Dan Abromov(Redux의 아버지)는 Functional Programing을 바탕으로 Redux를 만들었습니다. 때문에 Redux에서는 Pure Function(순수 함수)가 매우 강조됩니다.

“MobX-Observable, Redux-Functional Programming”

실제 비즈니스 환경에서 사용되는 큰 앱일수록, 전체 상태를 통제하는데 용이한 Redux를 사용하는 경향이 있습니다. 그러나 제 경험에 따르면 가끔 로직이 꼬이면 앱 전체가 패닉에 빠지는 경우가 있었고, 순간적으로 다량의 Dispatch가 발생하는 상황은 미리 예상하고 적절히 관리해줄 필요가 있었습니다.

3. Declarative한 개발

Facebook의 공식 React 메인 페이지에서 React를 소개하는 첫 단어가 바로 “Declarative”입니다. 보통 “선언적”이라고 번역되지만, 이해에는 별로 도움이 되지 않습니다.

아주 간단한 예를 들어보겠습니다.

import React, { Component } from "react";
class RockOfRian extends Component {
  constructor(props) {
super(props)
}
  render() {
return (
<div className="RianContainer">
<form>
<input type='text' value="Rian" />
<input type="submit" value="Submit" />
</form>
</div>
)
}
}

여기서 render라는 method가 return하는 것은 언뜻 보면 DOM처럼 생겼지만 실제로는 React가 만들어내는 Virtual DOM입니다. 나중에 React는 이 Virtual DOM을 보고 브라우져에 실제 DOM을 생성합니다.

Virtual DOM은 실제 DOM이 아닙니다. Virtual DOM이 어떤 과정을 거쳐 실제 DOM으로 바뀌는지 여기서는 알 수 없습니다. 그러나 Virtual DOM을 통해 실제 브라우져에 표시되는 UI의 모습, 적용된 데이터를 한눈에 파악할 수 있죠. 개발자 입장에서는 자신이 최종적으로 표현하고자 하는 것을 그냥 적어주면 되는 겁니다. 이것이 “Declarative”한 방식입니다.

“Declarative”한 방식의 개발은 코드를 한층 더 간결하게 하고, 개발자들이 더욱 원활하게 소통할 수 있도록 만들어 줍니다.

역시 Facebook에서 공개한 쿼리 문법인 GraphQL 또한 “Declarative”한 개발을 위한 시도입니다.

{ 
hero {
name
friends {
name
}
}
}

위의 코드는 영웅(hero)의 이름(name)과 그 친구(friends)들의 이름(name)을 보내달라고 요청하는 GraphQL 코드입니다. 형태만 보고도 어떤 데이터를 요청하는지 단번에 알아챌 수 있습니다. 클라이언트에서 필요한 데이터의 ‘모습’을 적어주면 서버가 그 모습대로 데이터를 보내주는 겁니다.

GraphQL

Relay는 각각의 React Component에서 발생하는 데이터를 GraphQL 문법으로 만들어 서버와 소통할 수 있게 해주는 프레임워크입니다.

쉽게 말해, Component가 만들어질 때마다 “이 Component는 이런 이런 구조의 데이터를 만들고 주고 받는 Component야!”라고 도장을 찍어주는 녀석입니다. 즉, Component를 데이터의 관점에서 정의합니다. Facebook은 Relay에 대해 ‘데이터가 주도하는 React 앱을 만들기 위한 Framework’라고 소개하고 있습니다.

Relay : A JAVASCRIPT FRAMEWORK FOR BUILDING DATA-DRIVEN REACT APPLICATIONS

저는 Relay대신 Apollo를 통해 GraphQL을 사용하고 있습니다. 아무래도 업데이트가 뜸한 Relay비해 발전속도가 빠르기도 하고(그러나 Relay Modern이 출시되면서, 많은 대형 기업들이 Relay를 도입하려고 준비하고 있습니다), Redux랑 궁합도 더 좋으며, Subscription같은 최신 요소들도 지원하기 때문입니다.

React Conf 2017: GraphQL이 Subscription을 통해 한층 더 강력해졌습니다.

GraphQL이나 Apollo는 아무래도 초기 러닝커브가 꽤 있습니다. 그러나 React와 GraphQL에 익숙해진 이후, 확실히 프론트엔드와 백엔드를 오고가는 작업이 훨씬 유연해진 것을 체감했습니다. 작업 중간에 예상치 못한 데이터 로직이 생겨도, 이에 대처하기가 훨씬 쉬워졌죠.

#너무 빠르게 변하는 Front-End 개발 환경

요즘 웹개발 환경이 너무 빠르게 변하고 있다는 것은 다들 동의하실 겁니다. 단, 몇개월만 느슨해져도 한참 뒤쳐져 있는 자신을 발견하게 되죠. 앞으로도 몇년간은 Front-End 세계에 안정이라는 것은 요원한 일일듯 합니다. 항상 업계의 동향을 놓치지 않고, 영어로된 개발문서를 두려워하지 않는 자세로 이겨나가야 될 듯 합니다.

Like what you read? Give Mungue Lee a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.