CommonJS와 AMD

CommonJS의 발단

자바스크립트 표준화와 관련된 첫 논의는 2009년 1월 케빈 댄구어(Kevin Dangoor)가 자신 블로그에 현재의 서버 사이드 자바스크립트가 필요한 것들을 역설하면서 시작되었다.

첫 시작은 서버사이드 자바스크립트였지만, 논의가 구체화 되면서 자바스크립트가 가장 많이 쓰이는 브라우저 뿐만 아니라 커맨드 라인툴 등의 일반적인 언어로써 논의로 확장되었다.

그리하야  CommonJS 등장한다. 뚜둥~!  케빈이 CommonJS 1년을 회고하며 쓴 글을 참고하자!

 

CommonJS 사이트가 자꾸 죽어요!

이유는 나도 모르지만, 여튼 종종 잘 죽는건 확실한것 같다. 이럴때 미러 사이트를 이용하자.

http://www.commonjs.org.mirrors.page.ca/

http://wiki.commonjs.org.mirrors.page.ca/

 

CommonJS와 AMD

내가 기고한 기사도 있지만 CommonJS가 모듈화만을 위한 워킹 그룹으로 오해하면 안된다.

CommonJS는 그보다 더 많은 주제를 가지고 토론하고 있으며, 모듈도 그 중 하나에 속한다. 물론 가장 활발한 논의중 하나고, 가장 많은 진전이 이루어졌다.

AMD의 시작은 CommonJS에서 시작됐지만, 브라우저라는 특별한 환경 때문에 결국 갈라서고 만다.

가장 큰 이유는 바로 require() 메소드의 동작 때문이었다. AMD는 브라우저에서 잘 동작하려면, 콜백 스타일의 require() 메소드를 만들어한다고 주장한 반면에,

CommonJS 쪽은 브라우저도 예외없이 동일한 본래 스타일의 require() 함수를 써야한다고 주장하며, 동기식 XHR과 eval() 을 이용한 모듈 로더를 제안한다.

하지만 AMD 진영은 동기식 XHR과 eval()은 디버깅도 어렵고, 크로스 도메인 문제가 있으며, eval()은 권장하는 방법이 아니라며, <script> 태그를 동적으로 헤더에 삽입하는 방법을 제안한다.

 

Lazy Loader

AMD 진영에서 주장한 <script>태그를 헤더에 삽입하는 방식 뿐만아니라, 동기식 XHR+eval() 방식 모두 필요할 때 모듈을 로드하는 방식이다.

물론 레이지 로딩 방식보다는 파일 하나에 퉁쳐서 내려받는것이 성능상 더 좋다! 하지만 뭐 사실 그렇게 눈에 띄게 큰 퍼포먼스의 차이는 없을수도 있다.

만약에 그 사소한 차이도 놓치도 싶지않다면, 당연히 파일을 하나로 퉁쳐야한다. 그래서 AMD 모듈의 경우 대부분 모듈의 의존성을 파악해서 파일을 하나로 퉁쳐주는 보조 툴을 제공한다.

RequireJS의 경우 r.js 라는 녀석이 바로 그런 녀석이다!

 

Backbone 간보기

언제부터인지는 정확히 모르겠다.

Backbone 이란 단어를 처음들은건 아마도 nodejs 책을 한창 번역중일때 였던듯 싶다. 그리고 간간히 Backbone이 대세다? 라는 소리도 들리길래, 언제 시간나면 좀 봐야지 했는데.. 이제서야 살펴봤다. ㅇㅎㅎ

Backbone 넌 누구냐?

난 Backbone이 node.js 모듈로 업데이트 받을수 있길래, socket.io와 같이 서버와 클라이언트를 동시에 아우르는 뭐 그런 모듈로 생각했었다. 그런데 막상 써보니 에헤라~!! 이건 완전 클라이언트 모듈이다! 그냥 라이브러리다!.

Backbone 홈페이지 가서 Backbone.js를 받아서, 쓰고자하는 페이지에 그냥 삽입하면 끝이다! ㅎㅎ 아~ 모를땐 막연했는데.. 역시 코드를 직접 만져보니 이런거구나 느껴진다.

Backbone에 대한 짧은 단상

일단 인터넷에 떠도는 튜토리얼을 가지고 하나하나 해보면서 느낀 소감은… 재!… 밌!… 다!!!! 무엇이 그렇게 재밌나?… 한마디로 정의하자면,.. 그냥 뚝딱 애플리케이션을 만드는 느낌이다!

초간단 테스트는 메인 페이지에....

마치 타이타늄을 가지고 노느는듯한 느낌이랄까?..  아직은 뭐가 뭔지 정확하게는 모르겠지만, 그냥 감으로.. 대략 이런게 아닐까? 하는 느낌은 있다. 내 감이 맞는다면.. 정말 재밌을것 같다. 틀리면,.. 뭐.. 그냥 하다 말겠지모..ㅋ

여튼  Backbone을 이용해 만들고 싶은게 하나 생겼다. 만들면서 컨텐츠를 하나둘 채워볼 생각이다. 그럼 기대하시라~ Coming Soon!

Blob 이미지를 SQLite에 저장하고 불러오기

Blob 객체란?

타이타늄 모바일에서 Blob 객체는 내부 데이터를 바이너리로 가지고 있는 객체를 의미한다.

The blob is an abstract data type that represents binary information, often obtained through HTTPClient or via files. It often is used to store text or the actual data of an image.

그리고 종종 이 객체를 그대로 데이터베이스에 저장하고 싶을때가 있다. 예를 들면 카메라로 찍은 이미지를 서버에 저장하지 않고, 그냥 앱안에 저장하고 싶은 경우가  있을수 있다. 이런경우엔, 보통 2가지를 생각해볼 수있다.

  1. SQLite 를 이용해 이미지를 앱 안에 저장한다.
  2. 찍은 이미지를 로컬 파일 시스템에 저장하고, Native Path를 DB에 저장한다.

여기서 다룰 내용은 바로 1번에 해당하는 내용이다. 그럼, 본론으로 들어가자!

Blob 이미지와 SQLite

타이타늄 모바일 커뮤니티 Q&A 게시판을 뒤져보면, Blob 객체를 SQLite DB에 저장하고 싶어하는 사람들이 많다는 사실을 알수있다. 하지만 그 어떤 누구도 뾰족한 해답을 제시해주지 못하고 있다.

SQLite에 쓰려면 직렬화 하세요!

문제의 핵심은 바로 SQLite DB에 있다. SQLite 가 지원하는 데이터 타입에 분명 BLOB 타입이 존재하지만, 자바스크립트에서 쓰는 그 Blob 객체가 그대로 저장된다는 의미는 아니다. 결국, DB에 데이터를 쓰려면 객체를 직렬화해야한다. 가장 간단한 방법은 객체를 문자열로 만들면 된다. 그럼, Ti.Blob 객체가 제공하는 toString() 메소드를 이용하면 되겠네? 라고 생각할수도 있지만, 결론은 안된다. 그럼 도대체 어쩌란 말인가???

바이너리 객체를 인코딩하세요!

결론은 base64로 인코딩했다가, 디코딩해서 쓰면된다.  코드로 써보면 다음과 같다.

// 저장할땐, 인코딩
exports.setImage = function(_rowId, _blob) {
    var mydb = Ti.Database.open(DATABASE_NAME);
    var sImg = Ti.Utils.base64encode(_blob);
    mydb.execute('UPDATE [table_name] SET blobImg="'+ sImg +'" WHERE  rowId="'+_rowId+'"');
    mydb.close();
};

// 사용할때, 디코딩
var db = require('db');
var encodedImg = db.getImage(rowId);
var blobImg = Ti.Utils.base64decode(encodedImg);

Summary

  1. save Blob image to SQLite

    var sImg = Ti.Utils.base64encode(_blob);

  2. use Blob image from SQLite

    var encodedImg = db.getImage(rowId); var blobImg = Ti.Utils.base64decode(encodedImg) ;

  3. but it is too slow in titanium, don’t use it!

덧,

몇가지 테스트해서 구현해봤더니 이미지를 DB에 때려 박는 무식한 방법은 쓰지 않는게 좋겠다. 이미지를 Base64로 인코딩하고 디코딩하는데 시간이 너무 오래 걸린다. 여튼 위 방법은 속도가 엄청 느리므로 비추한다.