지금 NW.js를 사용하여 데스크톱 애플리케이션을 개발 중에 있습니다. 그런데 상당히 Electron과 다른 점이 많네요. 적응하는 것도 꽤나 오래 걸릴 듯합니다. 이 글을 쓰게된 근본적인 사유는 렌더러 프로세스와 워커 프로세스가 분리된 Electron과는 다르게 둘이 각각의 Context로써 분리될 수 있는 NW.js에서 DOM을 어떻게 관리하고 사용해야 하느냐에 대한 고민입니다. 상당히 간단한 해법이었는데도 늦은 밤이라 그런데 늦게 떠올라 고생했네요.

간단히 글의 마지막에 정답이 있습니다.


Context

기본적인 Context 개념은 하나의 스코프라고 생각하셔도 됩니다. DOM이 함께 위치하여 있는 곳을 Browser Context라고 합니다. 반대로 Modular된 스크립트들은 Node Context라고 하는 곳에서 실행됩니다. 그리고 객체 nw는 모든 곳에서 전역으로 유효합니다. Electron에서 require('electron')를 사용하여 관리하는 것과는 약간 차이가 있습니다.

애플리케이션 Main 엔트리 포인트

엔트리 포인트는 package.json에서 main 속성에 명시됩니다. NW.js는 Electron과 다르게 HTML 파일을 엔트리 포인트로 설정할 수 있습니다. 물론 JavaScript 파일로 애플리케이션 윈도우가 표시되는 시점도 설정할 수 있습니다. 그러나 저는 약간 DOM과의 연결이 헷갈리는 관계로 HTML을 표시하기로 했습니다. 그 뒤에 Node.JS Context로의 연결을 해도 큰 관계는 없다고 생각했습니다.

향후 window 속성은 무엇을 엔트리 포인트로 지정하느냐에 관계가 없습니다. package.jsonwindow 객체로 추가 옵션을 명시할 수 있습니다.

Node Context에서의 DOM 사용

Node Context의 생성은 약간 예상 외였습니다. 저는 처음에 HTML로 엔트리 포인트를 잡고 시작했습니다. 그렇기 때문에 모든 것은 Browser Context 상에서 실행이 될 것이라고 생각했습니다. require 문을 사용하면 객체의 하위 프로퍼티로 객체가 연결되는 것이라고 생각했습니다. 하지만 하나의 모듈은 하나의 Context를 생성했습니다. 이는 제가 Chromium과 Node.JS의 스펙을 엄연히 헷갈린 것입니다.

현실이 이와 같이 분리된 Context로 동작하게 되었습니다. 따라서 미리 만들어둔 모듈의 전체적인 구조 수정이 필요하게 되었습니다. (막상 코드를 적을 때는 Node.JS Module의 구조를 완전히 따라갔습니다 :sigh:) 그리고 한 가지 의문이 더 생겼습니다. 그것이 어떻게 Node Context에서 DOM을 효율적으로 사용할 것인가 입니다.

http://docs.nwjs.io/en/latest/For%20Users/Advanced/JavaScript%20Contexts%20in%20NW.js/#access-nodejs-and-nwjs-api-in-browser-context

문서에 명시된 내용으로는 DOM이 Node Context로 참조될 수 있는 것 같습니다. 그래도 이는 너무나도 불편한 방법으로 DOM 자체를 하나의 변수로 모듈로서 매핑하면 어떨까 싶었습니다. 그런데 여기에서 몇 가지 문제점이 또 떠오릅니다. 웹 브라우저였다면 그렇게 큰 상관은 없습니다. 그러나 이는 데스크톱 애플리케이션으로 분리된 Context를 가졌습니다. 막상 HTML을 엔트리 포인트로 매핑한다면 완전히 큰 상관은 없었겠습니다. 하지만 여러개의 window를 사용한다면 해당 DOM이 사용가능하고 Deprecated되는 상황까지 고려해야 할 것입니다.

마지막으로 하나의 모듈에 DOM을 참조해주면 끝입니다. 아마 다음에는 왜 _cwd 변수를 사용했는지도 다루게 될 것 같네요. 감사합니다.