webpack을 이해하기 위한 javascript 모듈화의 역사

in kr •  7 years ago 

시작하며

Angular cli 툴을 써서 서버를 가동시키거나 빌드를 할때 터미널에 항상 뜨는 문구가 있다

webpack : Compiling...

Angular를 처음 접했을때는 이것이 뭔지 몰랐다. 그냥 필요한거겠지 하고 넘겼었는데,

점차 프레임워크를 파고들고 이해하는 과정에서 꼭 알아야 하는 하나의 관문같은 존재였기에

면접을 준비하면서 제대로 파헤쳐보자는 생각으로 조사를 실시하였다.

나는 맥락을 좋아한다. 전체적인 큰 흐름을 보지 않으면 답답해지고 불안해지는 이상한 정신병을 앓고 있다.

이번에 소개하는 자바스크립트의 모듈화는 아주 거대한 서사시의 일부, 삼국지로 치면 삼고초려같은 하나의 에피소드같은 단편적인 부분이다.

자바스크립트의 허점과 그를 해결하기 위한 움직임

자바스크립트는 웹에서 간편하게 쓰일 수 있도록 설계되었다. 하지만 시간이 지남에 따라 기술이 발전하고, 구현하고자하는 것이 많아지면서 점점 코드의 복잡화가 일어나기 시작했다. 하지만 자바스크립트는 그런 복잡도를 예상하지 못했기때문에 허점이 자꾸 드러나게 되었다.

그 허점의 근간은 전역 스페이스이다.

자바스크립트는 암묵적 전역이라는 개념이 있다고한다. 명시적으로 var라는 키워드를 쓰지 않은 변수는 자연스럽게 전역변수로 인식된다는 것이다. 이 문제는 중첩의 문제로 발견된다.

내가 a라는 변수를 써서 코드를 짰다. 1년 뒤 프로그램이 상당히 복잡해졌을때, 새로운 코드를 짜다가 a라는 변수가 있는지를 모르고 같은 이름의 a변수를 써서 작업을 시작했다. 이렇게 함으로써 전에 쓰던 a라는 변수를 1년뒤에 쓴 a로 덮어써버리게 되었고, 기능상 큰 문제를 야기하게 되었다.

이런 문제점을 해결하기위해 여러가지 방법들이 도입이 된다.

즉시실행함수는 전역을 건드리지는 않았으나 메모리상의 문제가 있었다.

네임스페이스 패턴은 더 나아가 메모리문제를 해결했지만 네임스페이스가 길어지고 복잡해지는 점과 검색하는 과정에서 많은 시간을 잡아먹었다. 전부 로딩시간에 큰 영향을 끼치는 것들이었다.

더 나은 방법으로 샌드박스라는 개념을 도입한다. 네임스페이스가 여전히 복잡도를 지니고 있는 것을 분산함으로써 복잡도를 낮추는데 성공하게 된다.

(참고 :http://www.nextree.co.kr/p7650/ )

모듈 시스템의 도입

한편, 허점을 극복하기위한 다른 방법도 제안이 된다.

소프트웨어 공학에서의 캡슐화라는 개념이 있다. 자바스크립트는 캡슐화에 대한 개념이 지원되지 않았다. 캡슐화는 자바스크립트의 허점을 해결해줄 수 있는 또하나의 방법이었다. 개발자들은 기존의 객체지향적인 편의성을 구현하기 시작했는데 그것이 모듈 패턴이었다.

자바스크립트의 모듈화 움직임은 현시점에 와서 크게 2가지가 대세를 이루는데 Common js 진영과 AMD 진영이다. 구현하고자 하는 것이 자바스크립트의 모듈화와 그 의존성관리라는 점에서 두 진영은 목표는 같았다. 다른 점이 있다면 브라우저환경에서의 해결방법의 차이이다.

Common 진영은 자바스크립트를 브라우저 밖에서도 활용할 수 있게끔 하는 차원에서의 모듈화를 지향했다. Common 진영의 한 부류였던 AMD는 브라우저를 좀더 고려했다고 볼 수 있는데, 의견 차이를 좁히지 못하고 따로 떨어져나왔다고 한다.

브라우저는 서버사이드와는 달리 스크립트 파일이 분리되어있어도 한 페이지에서 작동하게되면, 서로 네임스페이스가 충돌할 우려가 있기때문에 동기적인 것보다 비동기적인 처리가 우선되어야 했다. 이런 점에서 Common 형식은 서버사이드에서 좀 더 유연하고, AMD 형식은 브라우저 환경에서 좀더 유리하다는 의견들이 있지만, 큰 차이는 없다고 한다.

(참고: http://d2.naver.com/helloworld/12864,

http://blog.javarouka.me/2012/02/javascripts-pattern-2-module-pattern.html)

이러한 모듈화의 움직임은 결국 언어자체의 스펙을 바꾸는데까지 영향을 끼치게 되었다.

ES6 스펙부터 언어자체적으로 모듈개념을 도입했다. export와 import 키워드가 생겨남으로써 언어만으로도 처리할 수 있게 된 것이다. 이는 흐름을 이야기하는 이번 포스트에서는 자세히 다루지 않고 다른 포스트에서 더 자세히 다룰 생각이다.

(참고 : http://hacks.mozilla.or.kr/2016/05/es6-in-depth-modules)

부가적으로 이런 모듈을 쉽게 배포하고 저장할 수 있는 NPM 등도 생겨나게 되었다.

자바스크립트의 모듈화 움직임은 이렇게 다방면에서 일어나고 있었다.

모듈 번들러의 등장

모듈이 많아질수록 모듈이 서로 의존하는 트리가 복잡해지기 시작했다. 항상 모든 문제는 복잡함에서 일어나기 마련이다.

하나하나 다 의존성을 관리할 수 있겠지만 설정 파일하나를 설정해둠으로써 그 복잡함을 한방에 해결할 수 있을 것이다. 그래서 모듈 빌더 혹은 번들러라는 이름으로 다음과 같은 해결책이 나온다.

Grunt, Gulp, Webpack 등등...

흔히 자바스크립트 빌드 툴이라고 불리어지는데, 서로 추구하고자하는 목표가 조금씩다르기때문에 비교하는 것 자체가 어렵다고한다.

Angular cli 툴은 그중에서도 webpack을 채택해서 사용하고 있던 것이었다.

Angular cli 쓰려면 webpack을 알아야하느냐. 사실 꼭 그렇지도 않다. 서두에서 밝혔듯이 처음에 쓰고있을땐 webpack이 뭔지도 모르고 쓰고 있었다. Angular 가 이렇게나 훌륭한 프레임워크다.

하지만 내부적으로 어떻게 돌아가는지 정도는 알아두면 Angular cli 설정파일을 보는데도 조금은 이해가 될것이다.

https://www.facebook.com/218158748272233/videos/993595284061905/

생활코딩에서 30분짜리 영상을 볼수가 있다. 분명 webpack 의 전부를 이해하기는 어렵겠지만 이렇게 핵심만 알아두어도 내부적으로 어떻게 돌아갈지 가늠해 볼수가 있다.

마치며

이번 포스트를 통해서 정말 많은 것을 알게되었다. 평소 궁금했던 네임스페이스같은 것들은 물론,

샌드박스패턴의 개념도 알게되었다. Common js, AMD 라는 개념도 막연하게 알고 있었는데, 이런 상관관계들을 아는 것도 재미있었고 여기서 파생되어 나온 Require js 같은 것들이나 생태계의 일부로써의 NPM도 파악 할 수 있었다.

부가적으로 검색을 하다 알게된 사실이 하나 있다. 바로 자바스크립트의 && || 연산자의 쓰임이다.

아래에 메모로 적어두었던 것을 덧붙이며 포스트를 마무리한다.

자바스크립트 논리연산자는 신기하게 작동하는구나

즉 result = exp1 && exp2

가 있다고 했을때, true false로 값을 정한다

만약 exp1가 false 이면 뒤에것에는 상관없이

exp1 값을 바로 result에 넣는다.

만약 exp1 가 true라면 뒤에것도 확인해야하므로

통과시킨다. exp2값에 따라 true false가 정해진다.

그런데 자바스크립트에서는 객체 혹은 값의 유무에 따라 true false가 정해지기도한다. 바로 이점을 이용해서 간단하게 연산을 할 수도 있다는 점이 경이롭다.

|| or 연산자도 마찬가지이다.

result = exp1 || exp2 가 있다고 하자

만약 exp1 가 참이면 뒤에 값에 상관없이 참을 뱉을것이다 그러나 exp1가 false 이면 뒤에것도 확인해봐야 true인지 false 인지 정해진다 즉 완전히 반대로 작동한다는 것인데 이점을 이용해서 객체검사를 할 수도 있고 defalut 값도 줄 수 있다는 것이다

참 신기로운 자바스크립트의 세계!

플라이웨이트 패턴, 컴포짓 패턴도익혀두자.

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  
  ·  7 years ago (edited)

pairplay 가 kr-dev 컨텐츠를 응원합니다! :)