[Parse] Cloud Modulesの外部ライブラリ読み込みでエラーが出たときの対処
こんにちは。mBaaS担当(自称)のこむろです。
Cloud Codeで外部ライブラリを読み込む
Cloud Codeは、Javascriptの外部ライブラリを取り込むことができます。 すでに組み込み済みのライブラリについては、何も用意することなく宣言するだけで簡単に利用することができます。
組み込み済みのライブラリの場合
例えばUnderscore.jsは組み込み済みなので、main.jsの先頭に以下のように記述することで利用できます。
main.js
var _ = require('underscore');
組み込まれていないJavascriptライブラリを使う場合
例えば日時を操作する時に便利なmoment.jsを利用する場合には、 main.jsの先頭に以下のように記述することで利用できます。
main.js
var moment = require('cloud/moment-with-langs.js');
外部ライブラリとして取り込むjsファイルは、cloud/main.jsと同じ階層に配置しておく必要があります。
moment-timezone.jsのライブラリを取り込んでみた
本題です。 何も考えずに取り込みます。ファイル配置は先程のスクリーンショットの通り。
main.js
var moment = require('cloud/moment-timezone-with-data.js');
ParseにDeployします。
$ parse deploy Uploading source files Finished uploading files Update failed with Could not load triggers. The error was TypeError: Cannot set property '_z' of undefined at moment-timezone-with-data.js:325:29 at moment-timezone-with-data.js:14:20 at moment-timezone-with-data.js:18:2 at main.js:3:14
エラーが発生しました。
原因
エラーのStackTraceを見てみます。どうやらmain.jsのmoment-timezone.jsをrequireしようとしてる箇所でエラーが発生しているようです。 main.jsの記述には問題がないはずなので、moment-timezone.jsの中に原因があるようです。
moment-timezone.jsを変更する
該当箇所を探します。
//! moment-timezone.js //! version : 0.1.0 //! author : Tim Wood //! license : MIT //! github.com/moment/moment-timezone (function (root, factory) { "use strict"; /*global define*/ if (typeof define === 'function' && define.amd) { define(['moment'], factory); // AMD } else if (typeof exports === 'object') { module.exports = factory(require('moment')); // Node } else { factory(root.moment); // Browser } }(this, function (moment) {
見つけました。ここのrequireがParseでは呼び出されています。 当然moment.jsは、Parseに組み込まれていないのでこの呼び出し方はNGです。
以下の手順で修正します。
1.moment.jsを準備する。
moment.jsを取得して、cloud/moment.jsに配置する。
2.moment-timezone.jsを書き換える
moment.jsの呼び出しをParse用に書き換えます。
// module.exports = factory(require('moment')); // Node module.exports = factory(require('cloud/moment-with-langs.js')); // modify for Parse.com
以上の手順でOKです。Deployしてみます。
$ parse deploy Uploading source files Finished uploading files New release is named v49 (using Parse JavaScript SDK v1.2.19)
今度は問題なく成功しました。
まとめ
今回は、Cloud Modulesで外部ライブラリを取り込む際にハマった罠があったので記事にしてみました。
外部のJavascriptのライブラリを気軽に取り込めるCloud Modulesの機能ですが、ライブラリによってはこういった罠が待ち構えているので注意がに必要です。 ほとんどnode.jsと同じような記述で使えますが、こういった微妙な違いでうまく動作しないこともありますので、見つけ次第報告していこうと思います。