console.lealog();

@leader22のWeb系に関する勉強めもブログですのだ

Velocity.jsはnwjs(node-webkit)のv0.8.6では使えない

みんな大好きアニメーションライブラリのVelocity.jsですが、
残念なことにタイトル通りnwjsのv0.8.6では動きません。

nwjs

元node-webkitことnwjsは、20150221現在2つの安定版があります。

  • v0.11.6
  • v0.8.6

いわゆるlatestな方がnodeのv0.11(それでも11)を使っているので、
nodeの安定版であるv0.10.22をサポートしてるバージョンも同時運用されている、と。

latestな方ではエラーにならなかったので、特に問題なければlatestな方を。

使えない理由

まぁエラーが出るからなんですが。

Uncaught TypeError: object is not a function velocity.js:3691
Uncaught TypeError: Property 'resolver' of object #<Object> is not a function velocity.js:3681

Velocity.jsは、Promiseが使える環境ではPromiseを使うようになっていて、
それが幸か不幸か今回のエラーを引き起こすみたいです。

アニメーションの終わりのコールバックまわりでPromiseをresolveしようとするけどなんだかしかエラー。

原因に迫る

とりあえず色々調べてみたところ、nwjsのPromiseの実装がバージョンによって微妙に違うらしく、それでエラーになってる模様。

http://img.ly/system/uploads/008/887/167/large_diff-promise.png

コレはnwjsの独自実装なんかな?

本家にIssue立てて聞いてみたけど、
それはこっちの問題じゃねーっす!とのこと。

まぁごもっともなんですけど・・・、
コード読む限り、window.PromiseがtrueなだけでPromise使うってちょっと脆すぎやしねーかと思いつつ、
まあ取り付く島もない雰囲気を察したので諦めました。

もっと枯れてるAPIならともかく、あのPromiseですよーなんかいまいち納得できんぜよー

対処方法

私のケースはちょっと特殊で、上記Issueに書いた通りiframeで埋めた先でVelocityを使ってて、
その中のPromiseに手が届かなくてダメだったのですが、
そうじゃないならまだなんとかなります。

Promiseをなかったことにする

Velocity.Promise = null;

ライブラリのロード後になかったことにする。
過激派かも知れんけどどのみちモバイルサイトとかでPromise実装されてるわけない + 使ってないならアリかも?

Polyfillで

petkaantonov/bluebird · GitHubcujojs/when · GitHubを使って、

Velocity.Promise = require('bluebird');

まあ普通はこうすれば良いのでは!