LoginSignup
2
4

More than 5 years have passed since last update.

nw.js:require()したモジュールにDOMを使わせる

Last updated at Posted at 2015-06-30

はじめに

nw.jsにおいて、require()したモジュールにDOMを使わせる方法。

※どうしてもrequire()でDOMを使わせたいというこだわりがなければ、素直にHTML上で<script>タグで読み込ませるほうが簡単である。そうすればWindowコンテキストで動作するのでDOM前提のモジュールはきちんと動作する。普通はそうするよね。。

やり方

require()する前にglobalオブジェクトにDOMオブジェクトと同名のプロパティを作り、そこにDOMプロパティを代入する。
※起動時はWindowコンテキストで動作していることが前提。
Differences of JavaScript contexts · nwjs/nw.js Wiki


global.document = window.document;
global.navigator = window.navigator;
// DOMを使うモジュールのロード
var ko = require('knockout');
var jquery = require('jquery');

なぜこんなことをしないといけないか

例えばknockoutだとモジュールの実装が下記となっている。

knockout.jsの冒頭
(function(){
var DEBUG=true;
(function(undefined){
    // (0, eval)('this') is a robust way of getting a reference to the global object
    // For details, see http://stackoverflow.com/questions/14119988/return-this-0-evalthis/14120023#14120023
    var window = this || (0, eval)('this'),
        document = window['document'],
        navigator = window['navigator'],
        jQueryInstance = window["jQuery"],
        JSON = window["JSON"];
       .
       .
       .

もうひとつ。jqueryでの実装。

jquery.js
(function( global, factory ) {

    if ( typeof module === "object" && typeof module.exports === "object" ) {
        // For CommonJS and CommonJS-like environments where a proper `window`
        // is present, execute the factory and get jQuery.
        // For environments that do not have a `window` with a `document`
        // (such as Node.js), expose a factory as module.exports.
        // This accentuates the need for the creation of a real `window`.
        // e.g. var jQuery = require("jquery")(window);
        // See ticket #14549 for more info.
        module.exports = global.document ?
            factory( global, true ) :
            function( w ) {
                if ( !w.document ) {
                    throw new Error( "jQuery requires a window with a document" );
                }
                return factory( w );
            };
    } else {
        factory( global );
    }

// Pass this if window is not defined yet
}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
 .
 .

nw.jsの場合require()したときはNodeコンテキストで動作するのでグローバルオブジェクトはglobalである。そのため上のthisにはglobalオブジェクトが入り、うまく動作しない。事前にglobalオブジェクトにDOMプロパティを入れておくことでNodeコンテキストでもうまく動かすことができるようになる。
jqueryの場合はglobal.window = windowとしても動作するね。そのほうがいいかもしれない。

さいごに

この方法は十分に検証したわけではなく、自分が使いたいモジュールがたまたまこの方法で動いているだけかもしれないので気をつけること。万能かどうかはわかりません。。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4