Azureのfunctions上をnode.jsでプログラミングする場合、プログラムを修正する度、毎回funcionsにデプロイして動作確認する、という繰り返しは効率が悪いので、localでも同じソースが動く用な雛形を作ってみました。
localでも動くnode.jsの書き方
まず結論
適当な実行用ファイル、例えばrun.jsを用意して
// functionsメインのindex.js読み込み
var main = require("./index");
// index.jsに渡すcontextオブジェクト
var context = {
log:function(v){
console.log(v);
},
done:function(){
console.log("function complete");
}
}
// メイン処理
new main(context,null);
これだけでok。あとはこれを実行する。
$node run.js
こうすることで、functions上で動くindex.jsをローカルでも動かせます。
解説
functionsの構成
まず、funtionsはindex.js
とfunction.json
が最小構成になっています。メインの処理となるindex.js
は以下のようなソースが最小の形になります。
module.exports = function (context, trigger) {
// debug
context.log("ログ表示");
// メインの処理
// ・・・・
// functions終了処理
context.done();
}
ポイントは以下で
- module.exportsのfunctionの引数は2つで、
context
とtrigger
-
context
・・・functions内の独自オブジェクト -
trigger
・・・functionsに渡されるtriggerに関する値
-
-
context.done()
はfunctions終了処理で、これが呼び出されないとtimeout errorになるまでプロセスが残る - ログ表示は
console.log()
では無く、書いても何も表示されない。debugはcontext.log()
で、log window1に表示される
contextへの対応
つまり、ローカル環境で、ログを表示したり、functionsの終了処理を呼び出そうとすると、このcontext
オブジェクトをlocalで動作させる必要があります。
そこで、run.js
で、context
オブジェクトを用意してます。
// index.jsに渡すcontextオブジェクト
var context = {
// ログ表示処理
log:function(v){
console.log(v);
},
// 疑似終了処理
done:function(){
console.log("function complete");
}
}
これで、functions上で動作するindex.jsがlocalでも動作するようになります。
補足
ログ表示は上記でとりあえずは可能なのですが、context変数はこのままだとmodule.exports内でしか使えません。そこで、以下のように対応したのが現状です。
// グローバル?にデバッグ用変数用意
var debug;
// メイン関数
function main_function(){
// こうすることで、module.exports外部でもログ表示できる
debug.log("ログ表示");
// やりたい処理
// ・・・・・
// functions終了処理もここで呼び出せる
debug.done();
}
module.exports = function (context, trigger) {
// contextをdebugにセット。以降、debugを利用
debug = context;
// メインの処理
main_function();
}
もっとスマートな方法がある気がしてます。あればコメントお願い致します!
-
log windowはこちらを参考 -> Azure functions ログの参照方法まとめ ↩