본문 바로가기
정보/IT

Javascript Preprocessor

by 키운씨 2012. 2. 22.


Java 와 Javascript 는 C 개발환경과 다르게 Preprocess 기능이 제공되지 않는다

이번에 팀의 이슈사항으로 Preprocess를 이용하여 버전관리를 하자는 의견이 나왔다
#define 을 이용하여 코드를 선택적으로 분리하고 이를 고객에게 배포하자는 것이다
물론 원본소스의 가독성 저하는 감수해야 한다

그때는 나도 #define 문법을 제대로 써본적이 없어서 이렇다할 이견을 제시할 수 없어서 걍 그런가보다하고 말았는데
조사를 좀 하다보니 코드 분리를 통한 방식보다는 형상관리툴에서 제공하는 Versioning 을 이용하는 것이 오히려 더 편하지 않을까? 라는 생각이 들게 되었다

그래서 SVN 을 적극적으로 이용하자고 하고 싶었으나......
오랜기간 사용한 Sourcesafe 에 대한 익숙함인지 모르지만 저 위에 계신분은 형상관리툴을 바꾸실 의향이 진작부터 없었다는 것을 알고 있기에 감히 제안할 수가 없었다 (우리회사는 태초부터 Sourcesafe 를 사용하고 있다)

결국 Javascript 에서는 지원하지도 않는 Preprocess 환경을 알아보기 위해 이리저리 수소문(검색)해보았고 다음과 같은 시행착오를 겪어야했다

처음엔 js-preprocess 라는 프로그램을 이용하기로 했다

이 프로그램은 javascript 로 작성되어 브라우저에서 바로 실행해볼 수 있다는 장점이 있었다
하지만 js-preprocess 를 실행하여 eval한 스크립트 내용에는 이상이 없으나 firebug 로 디버깅시 해당 소스코드가 어떤 라이브러리를 로드하여 실행된 것인지 알기가 너무 힘들었다 (물론 전혀 정보가 없는 것은 아니었지만 사용하기가 불편하였다)
게다가 우리의 요구사항은 사용자에게 전달할 배포파일에 이미 preprocessing 결과가 적용되어 있어야하며 우리가 js framework 을 개발하면서 브라우저로 수정내용을 확인할때도 preprocessing 이 실시간으로 적용되어야 했기에 위의 두가지 사항을 만족시키기 위해 이를 서버에서 처리하여 실시간으로 다운로드 할 수 있는 방법을 모색해보았다

그래서 Rhino 를 이용하여 javascript 를 실행할 수 있는 환경을 구축하고 이를 Servlet 으로 서비스하려고 하였으나...
문제는 성능이었다
15000라인의 자바스크립트 문서를 preprocessing 하는데 2분이나 소요되는 기염을 토하였다 (^^)
ScriptEngine 을 이용한 가상의 실행 환경하에서의 자바스크립트 실행은 당연하게도 성능상의 문제를 일으킬 수 밖에 없었던 것이다
결국 도저히 사용할 수 없겠다는 결론으로 js-preprocess 는 제외되어 버렸다

그렇게해서 preprocessor 프로그램을 javascript 버전이 아닌 java 버전으로 찾게 되었는데 도중에 다음과 같은 내용의 문서를 찾기도 하였다

* 자바에서 preprocess 를 지원하지 않는 이유 (http://java.sun.com/docs/white/langenv/Simple.doc2.html#4078
No More Typedefs, Defines, or Preprocessor

Source code written in Java is simple. There is no preprocessor, no #define and related capabilities, no typedef, and absent those features, no longer any need for header files. Instead of header files, Java language source files provide the declarations of other classes and their methods.

A major problem with C and C++ is the amount of context you need to understand another programmer's code: you have to read all related header files, all related #defines, and all related typedefs before you can even begin to analyze a program. In essence, programming with #defines and typedefs results in every programmer inventing a new programming language that's incomprehensible to anybody other than its creator, thus defeating the goals of good programming practices.

In Java, you obtain the effects of #define by using constants. You obtain the effects of typedef by declaring classes--after all, a class effectively declares a new type. You don't need header files because the Java compiler compiles class definitions into a binary form that retains all the type information through to link time.

By removing all this baggage, Java becomes remarkably context-free. Programmers can read and understand code and, more importantly, modify and reuse code much faster and easier.


여하튼 계속해서 구글링과 위키피디아 검색으로 Preprocessor 프로그램을 몇가지 찾아내었고 그중 첫번째 후보가 pre-processor-java 이었다
pre-processor-java 는 이름 그대로 preprocess 작업을 수행하는 자바프로그램이다
바로 테스트 프로그램을 작성해보았고 이 역시 우리가 찾는 프로그램이 아니라는 것을 알게 되었다
보통 C 환경에서 사용하는 define 구문은 다음과 같다

#define __DEBUG true

하지만 pre-processor-java 프로그램은 multi language 를 지원하기 위해서 그런지 문장앞에 주석을 붙여서 처리하게 되어 있다

//#define __DEBUG true

사용상의 문제라기보단 일관성의 문제였다
때문에 바로 탈락되었다

그 다음 후보를 테스트해보기 전에 혹시 내가 preprocess 에 대한 기본지식이 부족해서 제대로 된 검색이 이뤄지지 않은걸까? 싶어서 위키피디아와 구글링을 통해서 preprocess 의 기초에 대해 조사해보았다

Preprocess 위키피디아 내용, C Preprocessor 의 사용법

별거없었다 걍 대학때 공부했던 내용 그대로다...

그 다음 후보는 Eclipse 의 플러그인 형태로 사용 가능한 자바 프로그램이었으나... javascript 를 지원하지 않는 관계로 바로 탈락되었다

다음으로는 pre-processor-java 동일한 사용법을 가진 javapp 라는 또다른 자바 프로그램이었다
바로 탈락...

자바 버전의 preprocessor 를 조사하면서 느낀것은 자바 환경에서도 define 문법을 지원하기는 하지만 에디터에서 해당 문장에서 발생하는 오류를 없애기 위해 주석문으로 작성하고 있다는 것을 알게 되었다
언젠가는 써먹을지도 모르지만 당장은 필요없음에 더이상 java 버전의 preprocessor 는 찾지 않게 되었다

그 이후에 알게된 내용은 define 문장에 대해 굳이 특정 언어에 제한할 필요가 있나?라는 생각이 들었다
어차피 Run time 이 아닌 Compile time 인데 해당 언어의 문법 오류쯤이야 별 상관없지 않나 하는거였다
해서 혹시나 java 에 define 을 작성하고 이를 C Preprocessor 로 실행한 사람이 없나 싶어 검색을 해봤더니
역시나 있었다 -> 자바에서 전처리문 사용하기

비주얼 스튜디오에 설치된 cl.exe를 이용하라는데...
내 뒷자리 C개발자에게 부탁해서 cl.exe 를 복사해와서 실행해보니 바로 dll 에러가 났다
그래서 해당 dll 도 복사해서 실행해봤지만 역시나 알 수 없는 오류(걍 뭔 내용인지 모르는)가 발생하면서 프로그램이 수행되지 않았다
덕분에 MSDN 사이트도 방문해봤다
하지만 별다른 소득이 없어 바로 포기...

그렇게 헤매던중 결국 최종적으로 선택한 프로그램은 mcpp 라는 프로그램이다
자주 가던 stackoverflow 사이트에서 C Preprocessor 로 검색해서 그중에 하나 겨우 건지게 되었다

샘플도 작성해서 돌려보니 만족스럽게 동작하였다 (mcpp.exe 복사해 넣고 자바코드 몇줄만으로 코딩 완료 ㅡ,.ㅡ)
별거 아닌 프로그램으로 약 3일간 여기저기 헤맨 결과다
특히나 처음에 문제가 되었던 성능에 대해서인데
역시나 C프로그램이라서 ScriptEngine 으로 수행해봤던 15000 라인의 javascript 문서를 1초도 채 되지 않는 시간에 처리해버렸다
앞으로 Rhino 는 거들떠보지도 않을거다

처음부터 이렇게 접근하면 되었을 것을...
그동안 작성한 샘플은 내 작업사이트에 올려놨다 -> OMNIBUSCODE.COM