トップ «前の日記(2015-11-09) 最新 次の日記(2015-11-11)» 編集

日々の破片

Subscribe with livedoor Reader
著作一覧

2015-11-10

_ NodeJSでちょとつまづいた

Chrome上で動かしている割と大きなシステムがあって、そのうちバックグラウンド側で動く(つまるところ、モデルということだが)スクリプト群に、コマンドラインインターフェイスを付けて動かしたくなった。

で、NodeJSを使う(同じV8だし)ことは決めて、7月ごろにインフラ用の環境を用意しておいたのだが、やっと手が空いたのでいじろうとして仰天した。

NodeJSのWebサイトには、LTSが4.4と書いてあるのに、環境は0.12とか出てくるじゃん。

で、NEWSを見たらいきなり4になったということで納得して(V8 v4.5の4なのか?)、さあ始めるかと始めたところ、ひっかかる。

元のスクリプト群が、リソースを突っ込むためのオブジェクトresを共有しているわけだが、すべてのスクリプトは次のように書いてある。

var res = res || {};
(function() {
    res.thismodule = {...};
})();

当然のように、NodeJS用に作ったローダースクリプトで、次のように書いた。

global.window = { alert: function(s) { console.log(s); } };
global.window.parent = global.window;
global.res = {};
global.window.res = global.res;
require('./foo.js');
...

でも何か動作がおかしい。それで何が起きているか見てみると

global.res = {};
require('./foo.js');
console.log(res); //=> {}
...

はて?

で、要するにvar res = (右辺を最初に評価してグローバルなresを見る)res || {};と考えていたら、var res = (まず全体を評価しているのでこれはvar resで宣言された)res || {};ということのようだ。(requireされたファイルのグローバルはモジュールに閉じられる)

「ということのようだ」は気持ち悪いのでまじめに調べると

A variable with an Initialiser is assigned the value of its AssignmentExpression when the VariableStatement is executed, not when the variable is created.
12.2 Variable Statement

なので、「右辺がついた変数の代入式の値設定は、変数の作成時ではなく、var宣言の実行時に行われる」。ということは、宣言したこのスコープでの空の変数が右辺に出現している扱いとなる、「ということのようだ」。

いずれにしても、しょうがないので、globalのスコープになるように自分でevalすることにして解決。

function load(s) {
  var buff = fs.readFileSync(s);
  eval.apply(global, buff.toString());
}
global.res = {};
load('./foo.js');
...

もっとうまい方法があれば知りたいところだ。

キャンベル V8 野菜ジュース 163ml×6個 マッドマックス 怒りのデス・ロード(字幕版)(ブレンダン・マッカーシー/ニコ・ラソウリス/イアイン・スミス/クリス・デファリア/コートニー・バレンティ/グレアム・バーク/ブルース・バーマン) Node.jsビギナーズガイド: サーバーサイドJavaScriptをマスターせよ! PRIMERシリーズ (libroブックス)(掌田津耶乃)

TODO: 瀧内さんからmodule.exportsを使うというのを教えて頂いたので、試す。

追記:結局vm.runInContextを使うことにした。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|

ジェズイットを見習え