thumbnail

develop

Vue 개발자였던 내가 이세계에서는 React 개발자가 된 건에 대하여🤭

상당히 혼모노스러운 제목에서 알 수 있다시피 나는 2년차 Front-End 개발자로써 Vue.js를 사용해왔다. 나름대로 이전 회사에서는 여러 프로젝트를 담당했고 node.js 개발도 겸했기 때문에 Back-End와 Front-End를 오가며 서버 개발자와 협업하고 실제 서비스 런칭까지 경험했다.

Vue.js의 부족한 생태계로 인해 어마무시한 React 생태계가 부럽기도 했지만 회사의 기술 스택을 함부로 바꿔버릴 수도 없을 뿐더러 개인적으로 Vue.js를 굉장히 접근성이 좋고 설계가 좋은 Web Framework로 평가하고 있기 때문에 React로 넘어가는 일은 없을 것이라 생각했다. 그러나 우연한 계기로 입사한 회사에서 React를 쓰게 되어 적응하는 과정에서 결국 나는 React에 완전히 빠져버리고 말았다.

👏 Vue.js vs React.js

Vue와 React의 가장 큰 차이라고 한다면 역시 JSX가 아닐까 싶다. 물론 Vue도 JSX를 사용할 수 있지만 Vue는 확장자 .vue에 SFC(Single File Components)로 명명되는 자체적인 템플릿에 의존한다. 굉장히 접근성이 높은 형태로 구성되어 있기 때문에 오히려 js를 잘 모르는 사람들이 쓰기에도 상당히 사용성이 좋지만 그로 인한 단점도 명확했다. DOM을 조작하기 시작하면 런타임 시점이 생각보다 이해하기가 어렵고 복잡하며, 순수한 ES Module이 아니기 때문에 내가 생각하는대로 동작하지 않는 경우가 많다. 쉽게 말해 Vue Instance에 대한 의존도가 지나치게 높다는 것이다. 물론, Mixin이나 Plugin같은 Vue만의 훌륭한 도구들이 있지만 Vue SFC에 비해서는 접근성이 상당히 낮은 편에 속한다. 2년 동안 개발하면서 Mixin은 불편해서 잘 쓰지도 않았고, Plugin은 분명 유용하지만 이 역시 Vue Instance에 종속되기 때문에 상당히 불편했다.

그에 비해 React는 JSX를 쓰는 만큼 정말 순수한 ES Module을 사용하고 있다. 괴상한 자체 파일형식도 필요 없고 바로 자바스크립트를 이용해 불러와 사용할 수 있다. 상태 관리 라이브러리가 파편화되어 있는 것은 아쉬운 부분이지만 이 또한 Context API로 충분히 커버가 가능했다. Vuex의 사용성은 상당히 높게 평가하지만 React로 넘어오면서 Vuex의 형태는 일반적인 순수한 자바스크립트의 구동 방식을 생각하면 조금 아이러니한 구조가 있다. React는 그냥 자바스크립트 위에서 개발하면 되지만 Vuex는 모든 것을 객체로 만들어서 수많은 설정 파일 위에서 프로그래밍한다고 생각하고 개발해야 한다. 그래도 필자는 Vue의 개발 편의성을 굉장히 높게 평가하고 있다. 사실 현재 React에서 개발하는 모든 것들은 Vue로도 그다지 어렵지 않게 구현할 수 있다.

👎 Create React App

React를 시작하면 제일 먼저 접하는 것은 단연 CRA다. CRA는 Vue CLI와 비슷하지만 조금 다르다. vue에서는 eject를 한다는 개념 자체가 조금 희미한 편이고 대부분의 Webpack 설정은 vue.config.js에서 chain을 통해 설정한다. vue cli의 설정 자체가 상당히 잘 만들어져 있어서 본인은 사용하면서 그다지 불편함을 느끼진 않았다. 게다가 Vue-cli 자체가 기본적으로 지원해주는 기능들이 많기 때문에 오히려 감탄하면서 사용했던 경험이 있다. 그러나 React는 기본적으로 준비되어 있는 것들이 별로 없고 대부분 여러 라이브러리의 조합으로 사용하게 된다. 덕분에 개발자에게 더 다양한 선택지와 가능성을 제공하지만 boilerplate의 파편화는 피할 수 없는 부분이다. 이 때문에 회사 입사 초기에는 eject가 된 상태로 관리가 안되고 방치되어 있는 React 패키지를 만나게 되었는데 이게 상당히 골때리는 부분이었다. 일단 이렇게 되면 CRA가 기본적으로 갖추어주었던 것들을 잘 사용하다가 버전 관리를 하는 시점에서 멘탈이 터져버리게 되는 자신을 발견하게 될 것이다. 때문에 조금씩 개인적으로 프로젝트를 리팩토링하면서 Dependency 다이어트를 시도했고, 그 과정에서 eject된 패키지를 봉합하여 다시 CRA로 되돌렸다. CRA Config Inject 툴로 다양한 것들이 있지만 최신의 개발을 지향하는 본인은 현재 가장 세련되었다고 판단되는 Craco를 사용하여 config 파일을 생성하여 관리하였다.

확실히 이러한 경험을 통해서 느끼는 것은 Vue는 바로 개발에 들어갈 수 있지만 React는 수많은 기술 스펙을 하나하나 고민해야 한다는 것이다. 굉장히 심플하고 가벼운 것은 장점이지만 이 때문에 하나하나 개발자가 도구들을 준비해야 한다는 것은 불편한 요소로 꼽힌다. 다행히 Vue.js로 개발을 하던 시절에도 Velog-client같은 React로 개발된 공개 프로젝트들을 보면서 학습한 것들이 있기 때문에 나름 빠르게 기술 스펙을 정리하고 적응할 수 있었다.

👍 React 생태계

확실히 넘어오니까 느껴지는 것은 어마무시한 생태계다......라고 하기에는 그렇게 거대하다는 느낌은 받지 못했다. UI 관련 라이브러리는 생각보다 적었고 사용성이나 성능이 Vue 쪽에 비해 부족한 것들도 꽤 보였다. 물론 어마무시하게 거대하고 대단하고 엄청난 라이브러리들도 즐비했기 때문에 확실히 넘어올만한 가치가 있는 생태계긴 하다. React-query, React-Draggable, React UseGesture 등을 보면 라이브러리들의 퀄리티가 상당히 높다는 것을 알 수 있다. 역시 머기업이 끼어 있으면 오픈소스의 퀄리티가 상당한 수준으로 올라간다.

하지만 착각하면 안된다. 아무리 대단하고 엄청난 라이브러리들이 즐비하다고 해도 결국은 자체적으로 구현하는게 제일 편하거나 필수적인 케이스들이 많다. "이렇게나 생태계가 큰데 왜 이런건 없지?" 싶은 경험들이 많았는데 개발하다보면 라이브러리라는 체제 자체의 한계점이 느껴질 수 밖에 없는 것 같다.

🤔 React hooks

Class Component 방식의 개발에서 fuctional Component로 진화하게 만든 가장 큰 원흉(?)이라면 역시 React hook일 것이다. 사실 React로 넘어오면서 가장 이해가 안되는 게 바로 이 React hook이였다. Vue에 비해 state가 정말로 observable하다는 점은 칭찬할만한데 지나치게 statefull한 요 형태가 뭔가 시대 착오적인 느낌까지 들었다. 이놈의 useEffect는 왜 이렇게 쓰는게 까다로운지... 지금도 그냥 적응하게 되서 state의 흐름이 머릿 속에 그려지게 되었지만 양방향인 Vue보다 state와 관련하여 복잡도가 상당히 높아진 느낌이다.

beforeMounted가 사라진게 매우 빡이 치는데 물론 직접 구현할 수는 있지만 굳이 코어에서 지향하는 방식을 사용하지 않고 솔로 마라톤을 하고 싶진 않았다. 특히 Vue는 Computed와 Watch로 명확하게 구분되는 기능들을 가지고 있는데 대체적으로 자주 바뀌고 캐시처리가 필요한, state에 대한 computed가 필요할 때 사용하는 것이 computed고 마치 DOM EventListener처럼 state가 변경될 때마다 함수를 호출하는 것이 watch다. 이 둘만 있으면 Vue를 다 배웠다고 해도 과언이 아닐 정도로 굉장히 유용한데 vuex와 활용하면 어마무시한 효율을 가진다.

하지만 React에서는 이해하기도 어려운 UseMemo를 사용해야 하는데 이건 아직도 사용하면서 좀 긴가민가한 부분이 있다. 과연 대 프레임워크 시대에 이렇게 어려운 형태를 가질 필요가 있었을까? 뭐, 대단하신 '프로' 개발자님들께서 이게 제일 효율적이라고 결론지었겠지.

결과적으로 지금은 react hook에 적응했고, 특히 react hook이 가지는 특유의 자율성 덕분에 Vue에서는 패키지 내에서 plugin을 개발해야 했던 그간의 설움을 위로 받았다. useEffect와 useMemo 욕을 그리도 했지만 함수 단위로 개발할 수 있게 된 것에 너무나도 감사하고 있는 부분이다. 진짜 써보면 안다. 써보면... 함수형 프로그래밍이 얼마나 쉽고 편하고 개쩌는지!

TypeScript

사실 Vue를 사용하면서 타입스크립트를 적용해보고 싶다는 갈망은 있었지만 정작 왜 타입스크립트를 써야 하는지에 대한 궁극적인 필요는 느끼지 못했다. 기본적으로 Vue는 (부분적)양방향에다가 대부분 type 시스템이 자체적으로 있다보니 propTypes 정도면 충분했었다. 무엇보다 그 당시에는 프론트엔드 개발을 내가 대부분 다 담당했었다. 비즈니스 로직을 두고 여러 개발자가 고민하는 등의 복합적인 협업은 크게 요구되지 않았던 것이다. 뭐 애초에 내가 사용하던 당시 Vue.js의 버전대는 2.x으로 지금의 React hook과 비슷한 무언가도 없었고 TypeScript를 지원하지 않았다. 방법이야 있지만 정식으로 지원하는 것도 아니었기에 불편함도 많았고, 사용 중인 라이브러리들의 대부분이 @types가 없어서 속빈 강정이었다.

그러나 React로 넘어오면서 함수형 프로그래밍을 짜기 시작하다보니 조금씩 정적 타입 언어가 가지는 불편함을 몸소 느끼게 되었다. 물론 propTypes라는 유용한 라이브러리로 컴포넌트 props의 불변성을 지켜줄 수는 있다(이 불변성을 이해 못하는 동료 개발자 때문에 더더욱 타입 제한이 필요했다...). 하지만 propTypes는 궁극적으로 다소 복잡한(어쩌면 본인만 그렇게 느끼는) React의 data flow를 해소하기에는 부족하다. 무엇보다 함수형 프로그래밍으로 넘어오면서 각각의 함수들이 기대하는 인자가 무엇인지 알아야 할 필요성이 생기는데 다른 프론트엔드 개발자와 협업을 해야하는 시점에서 TypeScript의 정적 타입 언어가 가지는 명시적 편리함은 타의 추종을 불허한다. 현재 개발 중인 서비스가 데이터 구조가 많다면 많고 서로 간의 관계를 생각하면 나름대로 복잡하다고도 할 수 있는데 기존에 개발된 스펙을 리팩토링하면서 API 명세서도 없고 당연히 일단적인 es6 다보니 명시된 Type도 없어서 데이터 구조를 이해하기 위해 기존 서비스를 돌려보고 이전 작업자에게 물어보는 등의 불편함을 감수해야 했다.

아 물론 그럼에도 불구하고 이 친구가 가지는 Value에 비해 다소 어려운 면이 있다. 타입 추론이라니? 정적 타입 언어라면서 막상 그 인터페이스는 전혀 정적이지 않다. 역시 개발자들은 자기네들만 아는 변태적인 무엇가를 구상하는걸 좋아하는 것 같다. 뭐 그래도 타입 추론을 알게 되면서 더더욱 그 편리함에 놀라고 있는 중이긴 하다. 다만 현재 본업에서는 언어를 쉽사리 바꿀 수 있는 체계가 아닌지라 토이 프로젝트로만 접해볼 수 있다는 것이 아쉬운 부분이다. 무엇보다 이 타입스크립트를 실제 현업에서 사용하기 위해서는 이미 팀 내에 소통이 어느정도 활발하고 문서화가 잘 되어 있어야 한다고 생각한다. 애초에 API 명세를 할 줄도 모르고 이렇다할 명세서도 작성하지 않으며, 그나마도 수기로 한땀한땀 쓰고 앉아있는 와중에 데이터의 불변성과 클린한 코드를 위해 TypeScript를 차용, 하나하나 뜯어보고 물어보면서 그 괴상한 데이터 구조를 받아들이며 Interface를 짜고 앉아있다면 그건 그거대로 정신병자다.

😆 드디어 개발자 컨퍼런스를 볼 수 있다!

이게 제일 훌륭한 경험이지 않나 싶다. 대부분의 프론트엔드 관련된 포스팅이나 컨퍼런스, 기술 소개 영상 등등의 다양한 미디어에서 보여주는 것은 React다. React 자체도 각종 라이브러리들이 React를 바라보고 만들기 때문에 어마무시한 호환성을 가지는데 지식에 대한 호환성도 역시 웹 프레임워크의 대표주자 답다.

https://www.youtube.com/watch?v=edWbHp_k_9Y 최근에 진행된 Toss #SLASH21 온라인 개발 컨퍼런스의 영상 중 일부이다. 이와 같은 컨퍼런스에서 항상 프론트엔드 파트는 React가 나오는데 아무리 JS를 다루는 Vue.js 개발자 할지라도 React를 잘 모르면 잃는 것들이 많다. 사실상 정보의 비대칭이 이루어지기 시작한다는 것이다. 많은 Vue 개발자들이 React 개발자로 전환하는 이유 중 하나가 바로 이것일 것이다. 고급 정보를 필요로 할수록 Vue는 자료가 너무 적다는 것이다. 이제 모두 React 개발자가 되어 이 방대한 정보의 세계에 빠져보길 바란다.

그리고 마지막으로 본인이 정말 개발자라고 생각하면 위 영상을 꼭 보길 바란다. 저건 머리로 이해하는 게 아니라 감각으로 인지해야 하는 부분이라고 생각한다. 정말 많은 개발자들이 추상화에 대한 이해도가 부족하고 코드 정리의 중요성을 간과하는 것들이 많다. 괜히 언어단, 프레임워크 단에서 저런 추상화를 돕는 다양한 개념과 기술들이 나오는게 아니다. 잘하는 개발은 저런 곳에서 나온다. 내가 PHP를 그다지 선호하지 않는 것은 저런 방법론을 적용하기에 커뮤니티의 기민함이 낮기 때문이다. 점진적으로 코드의 구조와 논리를 개선하고 실질적으로 개발 효율, 편의성, 휴먼 에러 감소, 관리적 이득을 모두 볼 수 있는게 이런 방법론들과 이에 대해 빠르게 대응한 언어, 프레임워크인 것이다.

우리 모두 우아하고, 세련되고, 모던한 개발을 하자.

미래를 달리는 IT인으로써...