티스토리 뷰


발생일: 2013.09.26

키워드: 노드웹킷, Node Webkit, NW, NW.js, 일렉트론, Electron, 크로미엄, Chromium, 크로스 플랫폼, cross platform

문제:
얼마 전에 노드웹킷(Node Webkit)을 사용해 프로토타이핑 하는 작업을 맡았었다.

나도 처음 접해보는 거였고, 살펴보면서 메모해둔 게 있어 옮겨둔다.


해결책:



소개

크로미엄과 노드를 활용해 네이티브 애플리케이션을 만들 수 있는 환경.
HTML, JavaScript, CSS 같은 웹 기술로 네이티브 앱을 만들 수 있다.

node-webkit slide
(슬라이드를 보면 어떤 컨셉인지 쉽게 이해할 수 있다.)


특징

- node.js의 함수가 렌더러 스레드에 존재한다.
- 즉, 페이지의 스크립트에서 노드의 함수를 호출할 수 있다.
- 다양한 OS를 지원한다. (Windows, Mac, Linux)
- 한 개의 소스로 여러 OS로의 패키징을 쉽게 할 수 있다. (App.nw)


그 밖에

- 대부분의 HTML5 기능을 지워한다.
- GPU 가속을 받을 수 있다.
- 비디오와 오디오를 지원한다.
- 기존의 cocos2d-html5 같은 라이브러리도 동작한다.


이런 것들이 가능

- 페이지에서 노드의 `fs` 모듈을 사용해 로컬 파일에 접근 가능.
- 페이지에서 `net`으로 소켓 통신 할 수 있다.
- 써드파티 노드 모듈을 자유롭게 사용할 수 있다.



어떻게 만드나?

- 간단하다! 노드 모듈을 만드는 것과 거의 동일!
- package.json
- index.html
- node_modules/


package.json

- name: 앱 이름
- window: 윈도우 사이즈를 지정한다.
    - window.width
    - window.height
    - window.toolbar: 툴바 보여줄 거니?
- main: 메인 페이지



어떻게 사용하나?

- 패키징 후 실행하기
    $ zip -r app.zip /path/to/your/app/*
    $ nw ./app.zip

- 스탠드얼론 버전으로 만들기 (사용자가 노드 웹킷을 설치할 필요 없다)
    $ cat /path/to/nw ./app.zip > app



구현 특징

- 노드와 크로미엄의 메시지 룹(message loop)을 머지했다.
    - 크로미엄은 MessagePump* 라는 걸로 내부 메시지 룹을 지원함
    - 노드는 libuv 라는 걸로 메시지 룹을 제공함
    - 노드웹킷은 libuv를 크로미엄의 메시지 룹을 사용할 수 있게, MessagePumpForUv 라는 걸 구현했음.
    - (즉, 메시지 룹을 하나만 사용한단 얘기)
- 노드의 심볼을 웹킷으로 추가했다.
    - 웹킷은 필요할 때에 자바스크립트 컨텍스트를 초기화함
    - 노드는 메시지 룹에 들어가기 전에 초기화함
    - 노드의 심볼은 웹킷이 DOM을 인스톨하자마자 추가됨
    - (즉, 웹킷에 노드의 글로벌 객체를 넣었다는 얘기)
- 웹킷의 보안 모델을 다운그레이드함
    - 웹킷은 사용자 액션에 의해서만 동작하는 기능이 있음 (예: File API)
    - 노드웹킷은 모든 스크립트는 사용자의 제스처로 동작한다고 가정함
    - 웹킷에서는 동일근원정책으로 크로스도메인 요청할 수 없음
    - 노드웹킷은 모든 페이지의 보안 토큰이 노드와 동일하게 사용함. 그리고, 로컬 페이지에 대해 전역 접근 기능을 줌.
    - (즉, 크로스도메인 요청 걱정하지 않아도 된다)



설치하기

각 OS 별 바이너리를 다운로드 받는다.

* npm으로 제공하지는 않는다.
  100% 자바스크립트 모듈은 npm 으로 설치할 수 있지만, C++ 모듈은 그렇지 않기 때문이다.

* 그래도, npm installer가 있기는 한데, 사용해보지는 않았다.


난 Mac OS 버전에서만 실행해봤다.
다운로드 받는 바이너리를 `Application` 디렉토리에 넣는다.

`node-webkit` 앱을 바로 실행하면 사파리 브라우저 같은 창이 뜬다.
여기서 개발자도구를 열면 (설정 아이콘) 콘솔에서 바로 노드의 객체를 호출할 수 있다.

예) var fs = require('fs');


터미널에서 작업하기 편하게 `~/.bash_profile`에 alias를 추가해두면 좋다.
# alias to nw
alias nw="/Applications/node-webkit.app/Contents/MacOS/node-webkit"



앱 만들기

기본 웹페이지를 만드는 것과 동일하고, `package.json`으로 앱의 이름과 메인 페이지만 지정해주면 된다.



트레이에 아이콘을 표시할 수 있을까?


트레이에 표시할 수 있고, 메뉴를 추가하고 click 이벤트를 할당할 수 있다.
하지만, 맥의 경우엔 click 이벤트를 할당할 수 없다.
click 이벤트를 할당할 수 없으면 의미가 없는데…

만들려고 하는 것 같다.



백단의 작업을 먼저 실행할 수 있을까?


브라우저를 띄우기 전에 뭔가 작업하게 하려 한다면,
`node-main`의 스크립트를 실행하도록 한다.



앱을 시작할 때 창을 숨길 수 있을까?


매니페스트 파일에서 `show` 속성의 값을 `false`로 설정한다.



앱 아이콘을 생성할 수 있을까?


패키징 후에 플랫폼 별로 별도로 만들어야 한다.



후기

웹 애플리케이션을 플랫폼 별로 앱으로 만들어 배포할 수 있는게 꽤 매력적이다.
그치만 아직은 안정적이진 않아서 제품에 쓰기엔 조심스럽다.
UI에서 노드 모듈을 사용할 수 있고, 파일 리소스나 디비 등에도 접근할 수 있어서,
어드민 툴로 활용하면 굉장히 유용하지 않을까 싶다.



---
2016.02.23 추가

꽤 오래 전에 정리했던 문서이지만, 기본적인 내용이라 아직까지 참고할만한 것 같아요.
(그 사이에 노드웹킷 이름도 NW로 바뀌었네요^^)

최근에 아는 분은 노드웹킷 대신 일렉트론(http://electron.atom.io/)으로 제품을 만들고 계시다고 하더군요.
전 일렉트론은 사용해본 적이 없어서 어떤 차이가 있는지는 정확히 모르겠어요.

그래도, 이제 막 작업을 시작하시는 거라면, 노드웹킷과 일렉트론 둘 다 살펴보시는 게 좋겠어요.^^
잠깐 검색해보니 장단점을 정리해놓은 블로그가 있네요.




반응형
댓글
공지사항