자바스크립트 학습 방법

이 포스트는 제가 다년간 자바스크립트를 설렁 설렁 공부하다 작년 1년동안 빡시게 공부해온 경험을 토대로 작성한 글입니다.
따라서 이 글을 읽으시는 분들께서는 본인과 맞지 않는 부분도 존재할 수 있으니 그 점은 참고하고 적절한 필터링을 하시면 되겠습니다.

목차

들어가기에 앞서

먼저 들입다 자바스크립트 공부를 하지 말고 아래 내가 열거한 사항들을 먼저 보고 공부를 해보자.
나의 다년간의 노하우가 녹아있으니 쏙쏙 빼먹길 바란다.
이러한 노하우들을 보고 실제 자바스크립트를 어떻게 공부해야할지에 대해 알아보자.
또한 에이전시/쇼핑몰에 종사하는 분들은 ES2015+를 실무에서 접할 기회가 적기 때문에 2-1. MDN, Stackoverflow와 친해지자 파트까지만 공부해도 실무에서는 전혀 무리가 없을 것이다.
하지만 스타트업, 자사 서비스/대규모 JS 앱을 개발하는 환경에 종사하는 분들은 ES2015+를 실무에서 매우 빈번하게 사용하고 있을 것이므로 그 이후 챕터까지 모두 공부하는 걸 추천한다.

역사를 먼저 알아보자

해당 프로그래밍 언어가 어떤 문제를 해결하기 위해 나왔는지 등등에 대해 파악을 하게 되면 좀 더 해당 언어를 잘 쓸 수 있게 된다.
먼저 초기 브라우저에는 페이지를 보여주기만 할 뿐, 유저와 상호작용을 하지 못했다.
유저가 값을 입력하는게 불가능하다보니 그에 대한 응답도 불가능했던 것이다.
따라서 페이지의 동적인 처리를 위해서 자바스크립트가 나왔다고 해도 과언이 아니다.
당시에 자바스크립트는 하나의 프로그램을 만드는 목적 보다도 ID에 공백을 넣은 경우, 메뉴에 마우스를 올린 경우 등등의 동적인 처리가 주된 목적이었다.
따라서 하나의 완성된 프로그램을 만들기에는 다소 부족한 점도 많았고, 10일이라는 짧은 개발 시간 탓에 설계 상 버그 등등이 많다.
이러한 점들은 자알쓰에서 하나하나 정리하고 있으니 해당 포스트를 참고해보자.

자바스크립트는 자바가 아니다

가끔 보면 자바스크립트 커뮤니티에 자바 질문을 올리는 사람들이 있다.
자바 스크립트(Java Script)가 아니라 자바스크립트(Javascript)다. 둘은 엄연히 다르다.
왜 이런 이름이 붙었는지에 대해서 간단히 알아보자.
자바스크립트의 이름의 변천사는 모카(Mocha) - 라이브스크립트(Livescript) - 자바스크립트(Javascript)이다.
자바스크립트는 다음과 같은 언어에서 영향을 받았다.

  • 자바에서는 문법과 ‘원시 값 vs 객체 관계’
  • 스키마와 오크에서는 일급 객체인 함수
  • 셀프에서는 프로토타입 상속
  • 펄과 파이썬에서는 문자열, 배열, 정규표현식을 빌려왔다.
  • 또한 워낙 여러 언어로부터 영향을 받은 덕에 함수형 프로그래밍(일급 객체인 함수)과 객체지향 프로그래밍(객체, 상속)을 함께 사용하곤 한다.

따라서 자바스크립트는 자바와 직접적인 연관 관계가 커서 그렇게 이름이 붙은 게 아니라 자바의 인기에 탑승하려는 노이즈마케팅 전략을 사용한 게 아닐까 싶다.

HTML, CSS의 연장선 상으로 자바스크립트를 바라보지 말자

많은 사람들이 HTML, CSS를 배우고 그 이후에 홈페이지를 동적으로 제어할 목적으로 자바스크립트를 배운다.
자바스크립트는 프로그래밍 언어이다.
C언어와 같은 프로그래밍 언어를 배운다고 하면 C언어를 배우지 그 전에 컴퓨터 사이언스를 굳이 배우고 시작할 필요는 없다.
배우면 좋지만 배우지 않고 시작해도 상관이 없다는 뜻이다.
즉, 그 말은 병행해도 된다는 뜻이며 HTML을 배우지 않고 JS를 먼저 배워도 된다는 뜻이다.

JS를 브라우저와 떼놓고 생각하자

브라우저에서 제공하는 JS는 크게 세 파트로 나눌 수가 있다.

  1. DOM(Document Object Model)
    자바스크립트에 자주 사용하는 document.getElementById()와 같이 document 객체에 해당하는 내용들을 지칭한다.
  2. BOM(Browser Object Model)
    자바스크립트에서 자주 사용하는 window.alert()와 같이 window 객체에 해당하는 내용들을 지칭한다.
  3. ES(ECMAScript)

오잉? 브라우저에서 제공하는 JS? 그럼 다른 곳에서도 JS를 쓸 수 있단 말인가?
그렇다. Node.js에서도 JS를 쓸 수 있으며 브라우저에서는 할 수 없었던 여러가지를 할 수 있게 되었다.

  1. File I/O
    파일의 입/출력과 관련된 내용이다.
  2. 서버 API
    서버를 구축하는 것 등등에 관한 내용이다.
  3. ES(ECMAScript)
  4. 기타 등등 너무 많음.

따라서 우리는 먼저 ES를 마스터해야한다.
Node.js와 Browser라는 플랫폼에서 공통적으로 쓸 수 있는 내용이기도 하며 ES에 해당하는 내용들이
여타 프로그래밍 언어들(C, Java 등등)이 가지고 있어야할 내용들(변수, 함수, 자료형, 조건문, 반복문 등등)이 포함된 내용이기 때문에
프로그래밍 언어 관점에서 자바스크립트를 배우려면 ES를 먼저 파야한다.

자바스크립트를 브라우저와 절친 먹여놓고 공부하기 시작하다보면 다음과 같은 함정에 빠지게 된다.
일반적인 수학에서 함수는 입력 값이 있으면 출력 값이 있다라는 개념이다.
프로그래밍 세계에서 함수의 입력 값은 매개변수, 출력 값은 반환하는 값과 연결이 된다.
따라서 두 수의 합을 반환하는 함수를 만들라고 하면 다양한 결과가 나오게 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 아래 두 케이스가 모범 답안
function add(x, y) {
return x+y;
}
var add2 = function(x, y) {
return x+y;
};
// 결과를 확인하려고자 하는 의지
function add3(x, y) {
console.log(x+y);
}
// 브라우저와 짱친 먹은 JS들
function add4(x, y) {
alert(x+y);
}
function add5(x, y) {
document.body.innerHTML += x+y;
}
function add6() {
var x = parseInt(prompt("숫자를 입력해주세요."));
var y = parseInt(prompt("숫자를 입력해주세요."));
document.body.innerHTML += x+y;
}

사람들이 입력이라고 하면 어느 정도는 함수의 매개변수로 이해를 하는 경향이 있다.(일부는 prompt 함수로 입력받는다.)
하지만 반환의 의미를 (화면에)출력으로 받아들이는 경우도 존재하고, 그 화면에 출력하는 방법도 로그창, 경고창, 브라우저에 보여주는 방법 등이 존재한다.
이는 모두 브라우저에 의존하고 있는 것이다.

JS는 더이상 Toy Language(장난감 가지고 놀듯 쉽고 깊이 없이 배워도 되는 언어)가 아니다.

과거에 어쨌든 간에 현재 자바스크립트는 계속해서 새로운 스펙이 나오고 이제 어엿한 프로그래밍 언어의 반열에 올랐다고 할 수 있다.
여전히 동적 타입, typeof 버그 등등의 단점이 존재하지만 이전 자바스크립트 버전으로 작성한 코드와의 호환 때문에 고칠 수 없는 점도 존재해서 여전히 문제는 존재한다.
하지만 예전의 Toy Language(장난감 가지고 놀듯 쉽고 깊이 없이 배워도 되는 언어)가 아니란 뜻이며 진지하고 깊숙하게 시간을 내서 배울 가치가 있는 언어이다.

어떻게 공부해야할까?

아직 들어가기에 앞서를 보지 않았다면 꼭 보고 오자.
공부에 임하기 전에 자바스크립트를 어떠한 자세로 바라보고 공부해야할지에 대해 적어놓았다.
이제 본격적으로 자바스크립트를 어떻게 정복해야할지 스텝 바이 스텝으로 적어보겠다.

1. 잘 만들어졌다고 알려진 언어들을 먼저 공부하자

사람은 아는만큼 보인다.
자바스크립트는 애초에 목적 자체가 프로그램을 만들기 보다는 페이지의 동적 제어였고, 10일이라는 짧은 개발 기간 덕분에 설계 상 문제점이 많은 언어이다.
이걸 다른 프로그래밍 언어를 모르는 사람은 그 설계 사항들이 왜 안 좋고 어떤 문제점들이 존재하는지 모른다.
그런 걸 친절하게 일일이 다 설명해주는 책이 있으면 모르겠지만 없었던 것 같고, 다 인터넷을 통해 파편화된 지식을 조각 조각 모아야했던 것 같다.
혹은 너무 어렵게 설명이 돼있거나…
하지만 잘 만들어졌다고 알려진 C나 Java와 같은 언어(동의를 안 하더라도 확실히 예전의 JS보다는 잘 만들어졌다는 데는 동의할 것이다.)를 먼저 공부하고 자바스크립트를 바라보면
이거 왜 이렇게 만들었어?, 이렇게 짜면 이런 사항들이 문제가 되겠는데?, 예전에 봤을 때는 못 알아 먹겠는 것들이 이제는 조금씩 보이네?하고 동일한 내용을 보아도 이해하는 관점이 깊이가 깊어진다.
따라서 나는 자바스크립트를 접하기 전에 그런 언어들을 먼저 접하는 걸 추천한다.

1-1. 그게 싫다면 쉽게 쉽게 쓰여진 책을 먼저 읽자

나는 시간이 별로 없거니와 C언어와 Java는 너무 어렵다(알레르기가 있다)고 생각되는 사람들은 사람들이 말하는 잘 쓰여진 책들 말고 서점에 가서 자신의 눈으로 직접 보고 이해할만한 수준의 책을 골라보자.
왜 잘 쓰여진 책보다 쉽게 쓰여진 책을 추천하냐면 일단 뇌를 말랑말랑하게 만들어서 자바스크립트와 친밀도를 높이게 하기 위함이다.
처음부터 잘 쓰여진 책을 보다보면 자신이 이해할 수 없는 수준으로 얘기하는 경우가 많다.
하지만 쉽게 쉽게 쓰여진 책은 다소 설명이 부족하더라도 이해하는데는 큰 무리가 없고 술술 넘어갈 것이다.
이런 책은 깊이 없이 그냥 술술 넘어가며 봐야한다. 그냥 ‘JS가 이런 거구나~’하고 맛보기만 하는 것이지 그렇게 깊이 있게 볼만한 책은 아니다.
주로 따라해볼만한 예제가 많고 브라우저와 짱친 먹은 예제들(눈에 바로 바로 결과가 보여지니 학습 유도에는 좋았다) 위주의 책이 보기 좋을 것이다.
나의 경우에는 HTML+CSS+JS 무따기 시리즈로 JS를 처음 접했는데 지금은 없어진 것 같다.

2. 소문난 책들을 위주로 읽자, 단 jQuery 빼고

여기서 말하는 소문난 책(내 기준)은 다음과 같다.

코뿔소 책이나 노란책도 유명하다고들 하나 솔직히 1독이라도 끝낸 사람이 얼마나 될까 싶을 정도라서 그닥 추천하지 않았다.
그리고 아직 읽어보지 않았지만 You Don’t Know JS 시리즈도 좋은 것 같다.

여기서 jQuery를 뺀 이유는 적어도 ES5까지는 알고 나서 제이쿼리를 접하는 걸 추천한다.
자바스크립트는 엄연히 프로그래밍 언어인데 중간에 jQuery(DOM 조작 라이브러리+@)를 먼저 접하면 프로그래밍 언어 관점 보다는 DOM을 조작하는데 너무 혈안이 될 수도 있다.
또 JS를 제대로 모르는 상태에서 jQuery를 접하게 되면 Javascript를 몰라서 나오는 질문을 jQuery를 모르기 때문이라고 생각할 수도 있으며,
Javascript로 해결해야하는 상황들을 jQuery의 메소드로 해결하는 상황도 초래할 수 있다.
jQuery는 Javascript로 만들어져있기 때문에 절대 VanillaJS(Pure JS)보다 성능 측면에서 좋을 수가 없다.
따라서 jQuery를 배우더라도 아직은 그 쪽에 힘을 싣지 않고 Javascript 쪽에 힘을 더 싣는 것을 추천한다.
jQuery를 사용하지 않는 곳을 찾기 힘들 정도로 jQuery는 많은 곳에서 사용 중이지만 아래와 같은 글이 있을 정도로 jQuery가 그렇게 짱짱맨인 것 만은 아니다.

2-1. MDN, Stackoverflow와 친해지자

  • MDN은 파이어폭스라는 브라우저를 만든 모질라 재단에서 만든 개발자를 위한 사이트이다.
    Javascipt 내장 API(Array 관련 메소드 등등)들의 자세한 설명 등등이 나와 있다.
    ECMAScript Spec을 보고 이해하기 힘든 내용들은 이 곳에서 자주 참고하자.
  • Stackoverflow는 개발자 계의 지식 IN이라고 보면 될 것 같다.
    검색은 네이버(카페)에 의존하기 보다는 구글링(구글에 검색하는 행위)을 통해 Stackoverflow와 같은 사이트 올라온 글들을 참고하자.
    네이버의 수 백 배에 달하는 글들과 더 좋은 정보들이 있다보니 더 빨리 문제 해결을 할 수 있는 가능성이 높아진다.
    한 발 더 나아가서 직접 질문과 답변까지 해보면 금상첨화일 것이다.
  • w3schools라는 사이트가 있지만 w3fools란 사이트가 있을 정도로 잘못된 내용 및 업데이트가 늦다보니 간단한 예제 정도만 참고하자.

2-2. ES5를 끝내고 ES2015+를 할 필요가 없다

웹 에이전시나 쇼핑몰 등등에 근무하는 사람들은 ES5까지(2-1 챕터)까지만 공부하셔도 업무를 보는데는 크게 지장이 없을 것이다.
웹 에이전시나 쇼핑몰에 근무하는 사람들이라면 ES2015+는 고사하고 ES3를 사용하고 있을 가능성이 크다.(IE8 때문)
그래도 IE8도 곧 사장될 거 같기 때문에(아마도…?) ES5를 미리미리 공부해두는 게 좋다.
또한 협업하는 사람이 ES2015+를 모른다면 다음과 같은 문제점이 존재한다.

  1. 협업하는 사람이 ES2015+를 공부해야한다.
  2. 협업하는 사람이 공부할 의지가 없으면 큰일이다.
  3. 추후에 사람을 뽑을 때 ES2015+를 알고 있는 사람으로 뽑아야한다.

이 외에도 다른 문제점들이 존재하겠지만 당장 떠오르는 것은 이게 끝이다.

해당 챕터부터는 스타트업이나 자사 서비스/대규모 앱을 JS로 개발하는 환경에 종사하는 사람들이라면 반드시 거쳐야하는 과정일 것이다.

과거 나도 ‘ES5를 끝내고 ES2015+를 공부해야하지 않나?’라는 생각 때문에 반년동안 ES5에만 목을 메달다가 어느 스터디에서 ES6(ES2015)와 ES5를 간단하게 비교해주는 내용을 들었는데 정말 혁명이었고 별 거 없었다.
ES6 들어서 새로 생긴 Promise, Generator, Iterator 등등의 내용을 다룬 것은 아니고 간단한
const/let, Rest Parameter, Default Parameter, Spread Operator, for-of 등등은 정말 금방 배울 수 있다.
따라서 내 생각은 똑같은 코드를 ES5로 짜보고 ES2015+로 짜보고 점점 익숙해지면 그 이후에 Promise, Generator, Iterator 등등의 내용을 공부하면 될 것 같다.
또한 요즘 프론트 엔드 개발을 할 때 ES5로 짜는 것보다 ES2015+로 짜는 경우가 훨씬 많다.
따라서 ES5를 공부할 필요가 없다고 주장하는 사람도 있는데 나는 그 견해와는 입장이 다르다.
ES2015+로 짠 코드를 브라우저(특히 MS 계열)에서 정상적으로 지원해주지 않는다.
따라서 ES5로 바꿔주어야하는데 결국 브라우저 위에서 도는 것은 ES5 코드이다.
그러니까 ES2015+로 짜면서 어느 정도는 ES5로 어떻게 변환될지 상상(?)을 조금 하면서 짤 필요는 있다.
ES2015+의 코드를 ES5로 바꿔주는 애가 100% 커버를 해주지 못한다. (그 도구가 꾸진 게 아니라 언어 설계상 오는 차이 때문에…)
따라서 대부분은 커버하지만 혹시 모를 에러가 발생할 수도 있으니 ES5 정도는 알아야한다는 게 내 생각이다.

3. NPM과 Babel을 배우자.

우선 ES2015+의 코드를 브라우저에서 100% 지원해주지 않는다.
따라서 ES5로 변환(트랜스파일)해줘야 하는데 그 중에 제일 많이 쓰고 좋다고 생각되는 것은 Babel이다.
이 Babel을 사용하는 가장 쉬운 방법은 Babel REPL을 이용하는 것이다.
그런데 매번 소스를 복붙 해서 트랜스파일하는 귀찮은 과정을 반복할 것인가?
그리고 우리는 바벨이 ES5로 트랜스파일 한 코드를 보고 이해하지 못한다.
따라서 우리가 소스 유지보수를 하기 위해서는 ES2015+로 짠 코드 하나, ES5로 트랜스파일 된 코드 하나, 총 두 개를 들고 있어야한다.
이런 귀찮은 작업을 줄여주기 위한 것이 babel-cli이다.
MS-DOS 유저라면 익숙할 법한 시꺼먼 창인 터미널(윈도우의 CMD)에서 트랜스파일을 해주는 도구이다.
하지만 이 babel-cli를 설치는 npm을 통해서만 가능하다. (왜냐면 babel-cli가 Node.js 위에서 돌기 때문…)
npm은 Node.js를 설치하면 자동으로 설치된다.
이 때 우리가 배워야할 것은 두 가지이다.

  1. npm 사용 방법(package.json에 대해 공부하기, 모듈 설치 삭제 해보기)
  2. babel-cli 사용 방법

4. ES2015+가 익숙해졌다면 Typescript를 공부해보자

ES2015+가 아무리 좋아졌다고 하더라도 다음과 같은 걸 해결하지 못했다.

  1. 정적 타입
  2. 사용자가 직접 인터페이스 구현
  3. private 접근 지정자
    등등이 있는데 이 ES2015+의 모든 특성들을 포함한 Superset 격인 Typescript란 게 존재한다.

나도 타입스크립트는 잘 모르기 때문에 1번을 토대로 장점을 설명해보겠다.

  1. 코드의 안정성
    앱의 규모가 커지면 커질 수록 코드를 파악하기 힘들어지는 경향이 존재한다.
    또 오랜 시간이 지난 코드를 유지보수 할 때도 마찬가지이다.
    이럴 때 어떤 메소드를 써야할 때 첫 번째 매개변수로 문자열이 와야하는지, 숫자가 와야하는지, 매개변수를 몇 개를 넘겨야하는지, 생략이 가능한지
    기존 동적 타입에서는 체크할 수 없었던 내용 등등을 체크하므로 어떻게 메소드를 사용해야하는지 직접 메소드 구현부로 가서 파악할 필요가 없어진다.
  2. 코드의 자동완성
    어떤 함수로부터 값을 반환 받았는데 이게 배열인 줄 알고 forEach 메소드를 썼는데 알고보니 Object가 반환되는 경우였다고 생각해보자.
    기존 동적 타입에서는 어떤 자료형이 반환되는지 모르니 자동완성에 배열의 메소드, 문자열의 메소드 등등이 전부 뜰 것이다.
    하지만 정적인 타입으로 딱 Object가 반환된다는 게 확정된 메소드라면 자동완성에 배열의 메소드도 뜨지 않을 것이며 배열의 메소드를 사용하면
    에디터 상에서 오류로 표시되기 때문에 이런 것도 어찌보면 코드의 안정성과 연결이 되는 점이기도 하다.

하지만 장점이 있으면 단점이 있듯, 내 기준에서 단점을 서술해보겠다.

  1. 생산성이 떨어진다(초기에)
    동적 타입인 js는 코드를 대충 빨리 짜도 돌아간다.
    따라서 생산성이 높다고 볼 수 있다. (하지만 나중을 생각한다면…)
    하지만 타입스크립트는 타입 체크가 매우 빡빡하다.
    따라서 동일한 코드를 짤 때도 더 오래 걸릴 수도 있다.
    하지만 나중에 되면 아마 타입스크립트가 훨씬 빠를 것이다.
  2. 외부 라이브러리에 대한 타입 정의도 모두 해줘야한다.
    이게 제일 사람 미치게 한다.
    유명한 라이브러리의 경우 미리 다 타입 정의 파일이 있는데 없는 경우에는 직접 만들거나 적폐 세력(any)를 사용해야한다.
    또한 라이브러리의 버전과 타입 정의한 파일의 버전이 불일치하는 경우도 있고 골칫거리다.
    이러한 단점 때문에 타입스크립트를 포기하는 경우가 많다. (나도… ㅠㅠ)

번외편

해당 파트는 자바스크립트와 직접적으로 관련이 있다고는 말할 수 없다.
하지만 나는 자바스크립트로 개발을 한다면(특히 ES2015+) 당연히 알면 좋다고 생각하는 내용들을 정리해봤다.

1. 코드 검사 도구를 사용하자.

코드를 짤 때 항상 일관성 있게 짜야한다.
하물며 한 사람이 짤 때도 문자열을 표시하는데 “”나 ‘’을 혼용한다던지
들여쓰기를 위해 탭과 들여쓰기를 혼용한다던지 등등의 경우에 놓이게 되는데
다른 사람들과 협업하다보면 하나의 소스 파일의 가독성은 똥망진창이 될 것이다.
하지만 사람의 눈으로 꼼꼼히 체크한다 해도 꼭 놓치기 마련이다.
이렇게 코딩 컨벤션을 지켰는지와 에러 등등을 체크해주는 툴로 JS에서는 JSLint, JSHint, ESLint 등등이 있다.
각자 장단점을 파악해보고 마음에 드는 걸 사용하면 좋은데 ESLint를 추천한다.
또한 TS 진영에서는 TSLint를 사용하면 된다.

2. Task Runner를 배우자

기존의 자바스크립트 소스 코드를 개발하던 방식에는 다음과 같은 문제가 존재한다.

  • 유저에게 불필요한 데이터를 전송하여 LTE 데이터를 낭비하게 만들고, 그 데이터들로 하여금 로딩 속도를 느리게 만듦으로써 사용자에게 최적화된 UX를 제공해주지 못하고 있다.
    이게 뭔소린가 싶으면 우리의 소스 코드를 보면 공백과 기나긴 변수명 등등을 가지고 있다.
    이거는 사람 입장에서 가독성을 높여 유지보수하기 편하게 한 것이지, 컴퓨터 입장에서는 이런 애들은 불필요하다.
    따라서 공백을 줄이고(minify), 변수명을 난독화(a, b와 같은 걸로 줄이는 작업, uglify)시키는 작업을 해야한다.

  • 우리가 사용하는 웹 브라우저는 HTTP 프로토콜 위에서 통신을 한다.
    요즘 HTTP 2도 나왔지만 아직까지 브라우저/서버의 호환 때문에 많은 사람들이 HTTP 1.1을 사용 중이다.
    HTTP/1.1는 기본적으로 Connection당 하나의 요청을 처리 하도록 설계 되어있다.
    그래서 동시전송이 불가능하고 요청과 응답이 순차적으로 이루어 지게된다.
    그렇다 보니 HTML 문서안에 포함된 다수의 리소스 (Images, CSS, Script)를 처리하려면 요청할 리소스 개수에 비례해서 Latency(대기 시간)는 길어지게 된다.
    SPA(Single Page Application)의 경우 다수의 스크립트 파일을 로딩하나 하나로 합친(concat) 스크립트 파일을 로딩하나 동일하게 작동한다.
    다수의 파일은 대기 시간이라는 오버헤드(쓸 데 없는 비용(여기서 시간도 비용으로 측정함))가 발생하기 때문에 다수의 스크립트 파일을 하나로 합쳐주는 작업도 해야한다.

이런 작업을 하는 방법은 여러 가지가 있는데 UglifyJS를 이용하는 것이 가장 간단하다.
하지만 이는 Babel REPL과 마찬가지로 수동으로 해줘야한다는 단점이 존재한다.
이러한 Minify 작업(Task), Uglify 작업, concat 작업 등등 무수한 최적화 작업을 소스 코드가 수정될 때마다 일일이 하고 싶을까?
이러한 작업(Task)들을 실행(Run)을 하나의 단위로 묶어서 한 번에 실행시켜주는 Task Runner란 게 존재한다.
그 중에서도 GruntGulp가 있는데 둘 중에 아무거나 해도 상관이 없을지 모르겠는데 나는 Gulp를 배웠다.

3. Module Bundler를 배우자.

자바스크립트에서 스코프는 함수 단위(const와 let은 블록 단위)이고, 모듈이란 게 존재하지 않았다.
따라서 네임스페이스 패턴과 같은 꼼수를 사용해서 모듈화를 구현하곤 하였다.

시간이 흘러 Node.js 진영에서는 CommonJS 스펙을 준수해서 모듈화를 구현하였다.
하지만 웹 브라우저는 사용자들이 파일을 내려받아야한다는 특수한 상황이 존재해서 비동기적으로 모듈을 로딩해야한다는 특수한 상황에 놓여있다.
이를 위한 AMD(Asynchronous Module Definition) 스펙이 있고, 이를 구현한 RequireJS라는 라이브러리가 있다.
자세한 내용은 JavaScript 표준을 위한 움직임: CommonJS와 AMD를 참고하자.

하지만 ES2015에 들어와서 Module을 언어단에서 지원해주는 import와 export 문법이 존재한다.
하지만 현재 이를 지원하는 브라우저/Node는 없다.
따라서 브라우저 진영에서는 여전히 A 모듈, B 모듈 등등을 각각 로딩해야하는 사태가 발생했는데 이 때 구세주처럼 등장한 게 Module Bundler이다.
Bundle은 ‘꾸러미’라는 의미로 하나로 합친다는 의미를 지니고 있다.
Task Runner의 concat은 단순히 소스 코드 자체만을 합치지만 이 Module Bundler는 모듈 간의 관계를 전부 파악해서 단일 모듈(소스 파일)로 Bundling 해준다.
따라서 Task Runner에서는 불가능한데 Module Bundler에서는 다음과 같은 것들이 가능하다. (설명은 Webpack 기준)

  1. Code Splitting(코드 분할)
    1. 변경률이 적은 서드파티(제이쿼리, 리액트 등등의 라이브러리나 프레임워크)들을 따로 빼서 사용자의 임시 파일에 저장시켜놓고 방문할 때마다 해당 내용을 캐싱하게 끔 해서 좀 더 로딩 속도를 높이기.
    2. SPA라고 해도 사용자가 모든 URI를 방문하는 게 아니니 URI 별로 소스 코드를 빼기.
    3. 그런데 URI 별로 소스 코드를 빼도 파일의 크기가 너무 작은 경우에는 오히려 요청/응답에 대한 오버헤드가 클 수 있으므로 소스 코드의 최소한의 크기 정하기.
  2. Tree Shaking(나무의 가지를 흔들어 썩은 열매를 떨어뜨리 듯, 필요없는 코드들을 삭제하기)
    쓰지 않는 코드(변수 함수 등등)들이 있는 경우에 자동으로 번들링 할 때는 없애기.
  3. 파일의 크기가 작은 경우에는 Data URL로 리소스를 표현하기(폰트, 이미지, svg 등등)
    웹팩에서는 js 소스만 모듈로 보는 게 아니라 정적인 리소스들(이미지, 폰트, svg 등등)을 모두 모듈로 보고 있다.
    그래서 이 모듈(정적인 리소스)들을 컨트롤 할 수 있게 된다.
    그런데 이미지 크기가 너무 작은 경우에는 요청/응답에 대한 오버헤드를 줄이기 위해 sprite image를 이용할 수도 있고, Data URL을 이용할 수도 있다.
    하지만 sprite image를 만드는 것은 귀찮고 사용하기도 불편할 때가 있다. (이를 위한 플러그인들도 많지만)
    그래서인지 모던 브라우저에서는 이런 Data URL을 통해서도 그런 오버헤드를 줄일 수 있다.
    물론 성능은 sprite image가 Data URL보다 더 뛰어난 것으로 알고 있다.

원래 Module Bundler 성격은 모듈과 관련된 것만 다루는 것이었는데 이제는 Task Runner의 기능까지 삼켜서 minify, uglify 등등의 기능까지 흡수를 해서 어지간하면 Module Bundler만 사용해도 될 정도이다.
하지만 Module Bundling 이전에 처리해야하는 특수한 경우에는 Task Runner에서 작업들을 처리한 이후에 Module Bundler를 돌려야할 것이다.
Module Bundler로는 Webpack, browserify, rollup 등등이 있는데
Webpack이 제일 사용자도 많고, github start도 많고, 커뮤니티 활성화도 잘 돼있으므로 Webpack을 공부하는 걸 추천한다.

4. TDD를 공부하자.

TDD(Test Driven Development)는 다음과 같은 개발 행위를 말한다.

  1. 테스트 코드를 먼저 짠다.
  2. 테스트 코드가 통과하게 앱의 코드를 짠다.

이를 통해 얻을 수 있는 장점은 다음과 같다.

  1. 내가 구현해야 하는 코드(테스트 통과)가 무엇인지 명확해진다.
  2. 코드를 수정해도 잘 돌아갈 거라는 안심이 된다.
    테스트 코드를 작성하지 않았으면 코드를 수정하고 해당 메소드를 사용하는 부분을 전부 다시 테스트해봐야한다.
    하지만 테스트 코드들을 작성했다면 해당 테스트를 통과했다면 수정한 메소드를 사용한 부분들이 정상적으로 동작한다고 볼 수 있으므로 심신에 안정이 찾아오게 된다.

TDD는 아니더라도 앱의 코드를 먼저 짜더라도 테스트 코드는 반드시 짜는 습관을 들이자.(나부터라도…)
하지만 많은 사람들이 아래와 같은 상황 때문에 TDD를 못하는 것 같다.

  1. 테스트 코드 짜는데 시간이 더 걸린다.
    초기에는 그럴지 몰라도 앱의 규모가 커지거나 유지보수를 생각한다면 TDD가 더 오래 걸리지는 않을 것이다. (더 적게 걸리지 않을 지도…)
  2. 어디서부터 어디까지를 테스트해야할지 모르겠어요.
    저도 모르겠어요… 누가 좀 알려주신다면 ㅠㅠ
  3. E2E(End to End) Test는 어떻게 하죠?
    저도 UI 단 테스트는 안 해봐서 누군가 피드백을 주신다면 수정하겠습니다.

이 TDD를 도와주는 프레임워크로는 jasmine, mocha, chai 등등이 있다.
그리고 이러한 테스트를 자동으로 돌려주는 등 위 프레임워크들을 도와주는 Test Runner인 karma가 있다.

마치며

내가 컴공을 전공하다 보니 비전공자나 입문자에게는 다소 딱딱하게 들리거나 어렵게 들린 내용이 많을 것이다.
다 내가 모르는 게 많아 이런 내용들을 쉽게 풀어내는 능력이 부족하기 때문이다 ㅠㅠ…
여튼 글을 보고 궁금한 점, 부족한 점, 잘못된 점 등등은 전부 댓글로 피드백 부탁드립니다~~

공유하기