JavaScript는 잘못이 없다. 정말로.
작년에는 이 글 JavaScript Fatigue, 요 몇 일 사이에는 이 글 How it feels to learn JavaScript in 2016(번역) 이 개발 커뮤니티 상에서 많이 돌아다니고 있다. 이런 현상들이 비단 2년 사이에 발생한 일일까? 2013년에도 이런 카툰을 본 적이 있다.
저 글들과 카툰 모두 아래와 같은 의식의 흐름을 통해 작성 되었을 것이다.
React(React-Native)라는 게 인기던데 한번 써볼까?
뭐야 내가 알던 JavaScript랑 다르네?
ES6? ES2015? Babel? Webpack? 뭐야 왜 이렇게 해야될 게 많아?
아 몰라 복잡해. 나 안해…
근 몇년 간 JavaScript, React, 관련 생태계의 변화를 직격으로 겪었던 사람 중 하나로서, 이런 의견들에 대해 공감하지 못하는 것은 아니다. 나 역시 똑같이 생각했던 사람 중 하나였으니까. 하지만 저렇게 문제가 많은 JavaScript와 React라면, 왜 수 많은 다른 개발자들의 관심과 찬양을 받고 있는 것일까? 분명 이유가 있을 것이다. 나 역시 역경의 시간을 이겨내고 적응하고 나니 그 매력을 알 수 있었고, JavaScript혹은 React가 받고 있는 비난들이 지나친 것이 아닐까 하는 생각이 들었다. 그리고 그 과도한 비난의 원인은 많은 개발자들의 가지고 있을 법한 오해와 편견에서 비롯되는 것 같았다. 이렇게 JavaScript 혹은 React가 비난을 받게 만드는 오해와 편견들은 무엇일까?
1. JavaScript를 잘 안다고 생각한다.
JavaScript를 어떤 언어라고 생각하는가? 초급 개발자들은 Java와 JavaScript가 어떤 연관이 있을 거라고 생각한다. 아니면 브라우저에서 클릭이나 팝업 이벤트 정도를 처리하는 정도의 역할만을 하는 단순한 스크립트 언어라고 생각한다. 동적 타입 언어이기 때문에 적당히 짜도 코드가 잘 돌아가긴 해서 사용하기 쉽다고도 생각한다. (그게 의도대로 돌아가는지와는 별개로.) 하지만 JavaScript를 조금이라도 진지하게 공부해본 개발자라면, 더글라스 크록포드의 JavaScript 핵심가이드 (원제: JavaScript: The Good Parts) 를 한번이라도 읽어봤다면, JavaScript가 그렇게 녹록한 언어가 아니란 걸 잘 알고 있을 것이다. JavaScript는 객체지향 언어이면서 함수형 언어이기도 하고, Prototype을 통해 상속 역시 지원하고 있다. 또한 일반적으론 싱글 스레드 환경에서 실행 되기 때문에 시간이 오래 걸리는 연산의 경우 비동기로 처리해야한다. 또한 언어의 설계 자체가 잘못된 부분들이 있어, 잘 모르고 개발 했다간 실수할 수 있는 부분들도 많다. 다시 한번 생각 해보자. 당신은 JavaScript에 대해 얼마나 알고 있는가? 많은 개발자들이 겨우 HTML 태그에 onClick 이벤트 한번 달아 본 경험으로 JavaScript라는 언어에 대해 잘 알고 있다고 생각 하고 있을수도 있다. 그리고 그런 생각으로 지금의 JavaScript 세상에 발을 들였다가는 서두의 글들과 같은 혼란을 겪게 될 것이다. 당신이 JavaScript를 등한시 했던 몇년 사이 JavaScript는 그 어떤 언어들 보다 빠르고 많이 변화했다. Node.js와 React.js등의 기술을 통해, JavaScript가 쓰일 수 있는 용처가 브라우저를 넘어 모든 플랫폼으로 확장 되었고, 스크립트 언어를 넘어 Java나 C++등의 자리를 넘볼 정도의 애플리케이션 개발용 언어로 발전했기 때문이다. 덕분에 기존에 JavaScript의 한계나 문제로 지적되었던 부분들이 빠르게 확장, 보완되고 있다. 당신은 기존의 JavaScript에 대해서 잘 알고 있는가? 그리고 JavaScript가 얼만큼 발전했는지 받아들일 준비가 되었는가? 만약 아니라면 JavaScript로 무언가를 하려고 하기 전에, JavaScript에 대한 학습부터 제대로 해야할 것이다.
(사족: 글의 제목이 ‘JavaScript는 잘못이 없다’ 이지만, 사실 잘못이 아주 없진 않다. 태초에 디자인이 잘못되어 모호한 this, 난해한 scope, private의 미지원 등 언어 자체가 엉성한 부분들이 많다는 것이다. 하지만 JavaScript가 세상에 나온지 벌써 20년이 훌쩍 지났다. 누구나 공공연히 알고 있는 문제는 보통 잘못이라기 보단 특징이라고 여겨지기 마련이다. 20년이란 시간이 흐르는 동안 이런 문제들은 JavaScript의 결함이 아니라 특징이 되었다. 게다가 ES6부터는 그런 결함들을 고치기 위한 기능들이 많이 추가되고 있다.)
2. JavaScript를 잘 한다고 생각한다.
1번을 별 이견 없이 통과했다면, 당신은 아마 JavaScript를 잘 아는 개발자일것이다. 그렇다면 당신은 JavaScript를 잘 하는 개발자인가? 다음 코드를 보자. 잘 짜여진 코드인가?
<div id="button">Click</div>
<script>
var $button = $('#button'),
clickButton = function () {
alert('Clicked!');
};
$button.on('click', clickButton);
</script>
사실 이 코드는 jQuery기반으로 짜여진 매우 정갈한 JavaScript 코드이다. 최적화 비용을 줄이기 위해 변수 선언을 블럭 최상위에 모아두었고, 함수 정의도 함수 표현식으로 하였다. 또한 엘리먼트 탐색 비용을 줄이기 위해 jQuery 객체를 변수에 할당 시켜놓고 재활용하기도 하였고, 콜백 중첩으로인한 가독성 저하를 막기 위해 이벤트 콜백도 인자로 전달하였다. jQuery를 기반으로 하는 고전적인 환경에서 개발을 했던 개발자들이라면 대충 이것과 비슷한 코드를 매우 많이 작성했었을 것이다. 조금 더 나아가면 Ajax를 통해 받아온 데이터를 기존 HTML에 추가하는 정도의 작업까지 했을 것이다. 이것과 비슷한 코드를 많이 작성해온 개발자라면 JavaScript를 잘 하는 개발자라고 할 수 있을까? 다른 언어로 한번 예를 들어보자. 아래는 한때 유행했던 개발 연차별 Hello World 코드 중 3년차 Java 개발자의 코드이다. (변수병과 괄호 위치가 신경쓰이지만 일단 넘어가자.)
상수 문자열은 별도 상수로 뽑아내고, 클래스의 행위와 상태 역시 깔끔하게 분리 했으며, 간단한 예외처리까지 해둔 깔끔한 Java 코드이다. 좋은 컨벤션으로 깔끔한 코드를 작성했지만, 그래봤자 이 코드는 Hello World다. 자 그럼 이제 Hello World를 깔끔하게 작성할 수 있으니 Spring 같은 프레임워크를 통해서 대규모 분산 처리를 할 수 있는 시스템을 뚝딱 만들어 낼 수 있을까? jQuery는 JavaScript 기본 API를 이용해서 하면 코드량이 늘어나는 작업들을 간결하게 사용할 수 있게 해주고, 기본으로 제공되지 않는 유틸리티들을 추가로 제공해주는 편리한 도구이다. 하지만 jQuery를 이용해서 할 수 있는 대부분의 작업들은 JavaScript만으로도 큰 비용 없이 구현할 수 있는 것들이다. jQuery를 아무리 능숙하게 다룬다고 하더라도, 그건 Java에서 단지 Apache Commons나 Guava같은 유틸성 라이브러리 API들을 많이 알고 있는 것과 비슷한 수준이다. Java를 다룰 줄 안다고 하더라도, Spring을 이용해 대규모 시스템을 만들기 위해선 우선 객체 지향에 대한 개념, 그리고 의존성 주입, 제어 역전, 관점 지향, MVC 패턴 등 알아야할 내용들이 아주 많다. 최근 JavaScript에서 인기 있는 기술들인 React, Redux, Angular2, RxJS등은 객체 지향, 함수형 사고, CQRS, 관심사 분리등 많은 사상들을 기반으로 하고 있다. JavaScript에 대한 경험이 jQuery뿐인 개발자들이 이러한 사전 지식 없이 바로 저런 기술들을 사용하려 한다면, 당연히 혼란스러울 수 밖에 없다. C에서 절차지향적 개발만 해오다가 갑자기 Spring으로 개발하려 드는 것과 같은 시도이다. 1번 항목에서 말했듯이, JavaScript는 객체 지향적이면서도 함수형 언어의 특성을 모두 가지고 있다. Underscore나 Lodash등의 라이브러리를 이용하면 보다 함수형 언어의 특성을 살려서 개발할 수 도 있다. ES5/6부터는 이런 라이브러리들이 제공하던 기능들이 언어 자체에 포함되기도 했다. React/Redux는 객체 지향적인 측면은 물론 JavaScript의 함수형 특징까지 매우 적극적으로 사용한다. (데이터 흐름의 단방향 성이라던가 데이터의 불변성 등.) 당연히 이런 기초 개념들에 대한 이해 없이는 사용하기 어렵다. 이것 역시 JavaScript의 잘못은 아니다. JavaScript는 예전부터 이런 특성들을 가지고 있었고, 아마도 JavaScript를 잘 하는 개발자들은 Prototype과 Closure와 같은 객체지향적, 함수적 특성들을 자유롭게 다뤄오고 있었을 것이다. 아마 그들은 React나 Redux의 등장에도 크게 당황하지 않았을 거라고 생각한다.
3. 프론트 엔드가 단순하다고 생각한다.
기술의 발전과 함께 사용자와 직접 마주하는 프론트 엔드의 코드의 위치는 계속 바뀌어 왔다. 윈도우 기반의 GUI 환경에서는 주로 대부분의 코드가 MFC(.NET 또는 Swing…)기반의 클라이언트 애플리케이션에 들어있었을 것이고, 클라이언트들이 점점 웹 기반의 분산 환경으로 변화하면서 HTML을 동적으로 생성하기 위해 많은 코드가 서버로 이동되었다. 그리고 모바일 시대와 함께 다시 예전의 GUI 애플리케이션 만큼이나 복잡한 모바일 애플리케이션들이 개발되기 시작했고, 지금은 웹에서 그런 형태와 기능을 제공하는 애플리케이션들이 제공되길 원하고 있다. 그렇게 Single Page Application(이하 SPA)이 탄생했다. Angular.js나 Ember.js등을 이용하여 한번이라도 SPA를 개발해본 개발자라면, 얼마나 많은 기능들이 서버에서 클라이언트로 이동 될 수 있는지 알 것이다. 그리고 더 나은 UX를 위해선 그런 변화가 필연적이라는 것도 알고 있을 것이다. 사실 이러한 구조는 예전부터도 기술적으론 가능했지만, 클라이언트(브라우저)의 성능 문제로 인해 많이 기피되어왔다. 하지만 최근 몇 년 사이 하드웨어(PC/모바일)와 소프트웨어(브라우저 / JavaScript Engine)의 성능 모두 매우 좋아졌기 때문에, 이제 클라이언트에서도 예전보다 많은 작업을 할 수 있다. 이미 모바일 앱에서는 대부분의 처리를 앱에서 수행하고 서버는 그저 데이터를 위한 API로만 사용되고 있는 것이 일반적이다. 웹 역시 비슷한 방향으로 발전하고 있다. 장기적으로 서버에는 Database또는 다른 API와 애플리케이션간의 연결 역할만을 하는 Gateway 역할만 남겨지고 대부분의 처리가 클라이언트로 옮겨질 것이다. 웹 프론트 엔드가 예전의 윈도우 클라이언트 만큼이나 거대하고 복잡한 애플리케이션이 되고 있는 것이다. (이미 Microsoft만 하더라도 Office를 웹 기반으로 제공하고 있다.) 하지만 수 많은 개발자들에게아직도 웹 프론트 엔드는 위에서 보여준 jQuery기반의 절차적 코드 수준으로 여겨지고 있다. 당연히 저기다 라이브러리 한두개 더 쓰는 기분으로 덤벼들었다가는 혀를 내두르며 나가떨어질 수 밖에 없을 것이다.
4. React로 모든 것을 할 수 있을 것이라고 생각한다.
React는 홈페이지에서도 스스로 말하고 있듯이, ‘A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES’ UI개발만을 위한 기능을 제공하는 라이브러리이다. MV* 구조에서 V만을 제공한다고 말하기도 한다. 잘 알려져있듯이 React를 만든 Facebook은 PHP를 기반으로 하는 Hack이라는 언어를 기본 언어로 사용하고 있다. FullStack JavaScript 구조가 아니다. 기본적으로는 PHP 애플리케이션들과 비슷한 방식으로 구현이 되어있을 것이고, 프론트 엔드에서 동적으로 변경되어야 하는 부분들에만 React를 적극적으로 사용했을 것이다. (그 비중을 점점 늘려가고 있는 중인 것 같지만.) Facebook에서는 처음부터 React를 이용해 모든 기능을 제공하는 프레임워크가 필요가 없었을 것이다. Facebook과 같이 이미 존재하는 시스템에 추가하기 위한 용도로 React는 아주 편리한 도구이다. React로 새로운 기능을 개발한다고 하더라도, 대상이 될 HTML 태그의 ID만 지정해주면 그곳에 React를 기반으로 하는 기능이 추가된다. 또는 이미 JavaScript를 기반으로 하는 시스템이 구축되어 있다면 View Layer만 React로 교체할 수 있다. (Angular, Backbone, Metor 등) 반면 React 하나만 가지곤 전체 애플리케이션을 만들 수 없다. 그게 React의 개발 목적이 아니었기 때문에 Facebook에서는 그런 기능들을 처음부터 제공하지 않았다. 하지만 React의 매력에 푹 빠진 개발자들은 React로만 전체 애플리케이션을 구축하길 원했고, React로 전체 앱을 개발하기 위한 서드파티 라이브러리들이 생겨나기 시작했다. 하지만 React와 Flux를 제외하곤 그 어느 것도 Facebook에서 공식으로 제공하는 라이브러리가 아니었기 때문에 개발자들과 오픈소스 커뮤니티들은 수 많은 시행착오를 겪었다. 이 시기에 React 개발에 뛰어든 수 많은 개발자들이 혼란을 겪었을 것이다. 매일같이 Best Practice가 바뀌고, 달마다 기반 라이브러리가 업데이트 되거나 변경되었다. 하지만 이것을 React나 Facebook의 탓으로 돌리긴 뭐하다. Facebook은 처음부터 자신들이 원하던 목적에 맞는, 단순한 라이브러리를 만들었을 뿐이고, 좌충우돌 하면서 혼란과 발전을 만든 것은 개발자들 스스로였다. Facebook에서 그랬던 것 처럼, 존재하는 시스템에 React만 곱게 올렸다면 그런 혼란들은 겪지 않았어도 되었을 것이다. (React-Native역시 마찬가지.)
5. 알아야 할 게 너무 많다고 생각한다.
ES6, Babel, Webpack, NPM(Node.js)…최신의 JavaScript와 React를 사용하기 위해 당신이 알아야할 키워드들이다. 더 많은 기능들을 사용하고자 한다면 다른 것들도 필요하겠지만, 일단은 이정도만 알아도 사용은 할 수 있다. 많아보이는가? 그럼 이렇게 생각해보자. Java5를사용하다가 Java8의 새로운 기능을 공부해서 Javac로 컴파일을 하고 Ant, Maven또는 Gradle로 의존성과 Task를 관리하는것. 복잡해 보이는가? ES6는 그저 JavaScript의 새로운 기능일 뿐이고, Babel은 컴파일러며, Webpack은 빌드 도구, NPM은 의존성 관리자일 뿐이다. Webpack의 설정이 복잡하긴 하지만, Ant, Maven, Gradle의 설정 파일들을 처음 볼 때도 비슷한 기분이었을 것이다. 최근 1–2년간 이러한 도구들이 안정화 되고 대세가 굳혀지는데 시간이 걸린 것은 사실이다. 하지만 지금은 이전에 비하면 매우 안정된 시기이며, 업데이트나 변경사항도 그렇게 많지 않다. 만약 당신이 JavaScript를 잘 알며, 잘 하고, 애플리케이션 구조 변화에 대한 패러다임(서버->클라이언트)에 대해서도 잘 알고 있으며, React 자체의 한계에 대해서 명확히 인지하고 있다면, 필요한 것이 그렇게 많은 것도 아니다. JavaScript가 예전처럼 .html 파일안에 인라인으로 날코딩 하는 언어가 아니라, Java와 같이 완전한 모듈로 관리되고, 그로 인해 의존성 관리와 빌드 과정이 필요한 언어가 되었다는 것을 알고 나서도 저런 도구들이 많다고 느껴지는가? (당신이 지금부터 만들 프로젝트는 예전 Visual Studio에서 만들던 윈도우 클라이언트만큼, 또는 iOS/Android 앱 만큼이나 크고 복잡할 것이다.)
누가 JavaScript에게 돌을 던지나?
어떤가. 만약 당신이 최근의 JavaScript에 대한 불평들에 공감했었다면, 당신이 위의 5가지 편견이나 오해 중 하나라도 가지지 않은 사람이라고 말할수 있을까? 사실 많은 불평들이 개발 환경이나 레퍼런스에 대한 투정이기도 한데, How it feels to learn JavaScript in 2016 반박글인 How it actually feels to write JavaScript in 2016(번역)에서 언급한 create-react-app과 같은 도구나 Walmart에서 발표한 electrode, Paypal에서 제공하는 react-engine, Facebook에서 직접 공개한 React-Native Sample인 F8 App등 큰 서비스들에서 제공하는 좋은 레퍼런스들이 많아 졌기 때문에, 환경에 대한 투정도 이미 지난 이야기라고 생각한다. JavaScript도 이젠 대규모 애플리케이션을 만들어 내기 위한 하나의 완전한 언어가 되었다. 심지어 최근의 트렌드인 함수형 패러다임도 아주 잘 지원한다. 당신이 지금부터 사용해야할 언어가 Scala, Haskell, Go였다고 하더라도 그렇게 얕보고 덤벼들었을까? 최신의 JavaScript는 저런 언어들과 크게 다르지 않아보인다. 어렵다고 복잡하다고 투정부리기 전에 JavaScript에 대해 얼마나 진지하게 생각해보았었는지 한번 돌이켜 보자. 이전과는 JavaScript가 다르게 보일 것이다.
JavaScript는 잘못이 없다. 정말로.