読者です 読者をやめる 読者になる 読者になる

愛と勇気と缶ビール

ふしぎとぼくらはなにをしたらよいか

Marionette.jsを使ってみている

最近Marionette.jsを使ってみている。

時は未だにJSフレームワーク大戦争時代、なんでMarionetteなんですか?って話なんだけども、

  • 作ってるのが管理画面に毛が生えたようなものなので、別にそんなパフォーマンスとか考えなくていい
  • だから別にReactとか、DOM周りに工夫が入ってるやつじゃなくてよい
  • 深遠な理由によりIE8に対応できるようにしておく必要があった
    • この時点でいくつかのフレームワークは除外される
    • Backbone系列には古いブラウザでも動きそうな謎の安心感がある
  • Angularは個人で使ってみて好きじゃなかったので除外

この辺の理由です。ゴリゴリって訳じゃないんだけど、ちょっとリッチクライアント?的なものだからBackbone + Marionetteくらいの塩梅がええかなー、と。

実際、真面目に使ってみたらBackboneとMarionette、特に前者は老舗だけあって中々良く出来てるなー、と思った。それだけだと何とも出来ない部分は多いけど、「自分はここまではやりまっせ」という線引きは少なくともはっきりしている。

別にこれは比較でも何でもないので、他のは知らんけどな。

フレームワークオタクになる時間もなる気もないので、あんまり最近のナウいやつは追ってないんだけども、今後の流れとして

  • 全体としてコンポーネント(modelとviewとロジックをくっつけて一つのまとまりを作って再利用する、その名前は何でもいいけど)志向になっている
  • それらの通信はevent的な何かで行うことになるのだろう(多分)
    • ここは最終何でもいいんだけど、event的なものが一番おさまりがいい気がしている。単にDOM Eventsが念頭にあるからだけど。

というイメージを持っている。

何らかのフレームワークに乗って気分良く作っていたとしても「Bootstrapのmodalを出さんといかん(ヒエー)」「XHRでPOSTした結果を何らか通知するようなUIがいる(ウヒョー)」みたいな要件は一杯あり、それらを全て気持よくカバーするフレームワークなんてものはおそらく存在しないので、実際の開発ではどうしてもフレームワークからはみ出した書き方をせざるを得ないことが多い。

なので、なんというか、「出来るだけはみ出しすぎないように書きつつ」「まあしょうがないよね、そういうもんだし」という気分でコードを書いている。

フレームワークの上に乗って、気分よく綺麗に書けるのはToDoアプリくらいなもんだ。

時間割を決めて行動してみる

2月の頭から有給消化モードに入り「このままだと無限にダラダラしてしまう可能性があるな」と思ったので、時間割を決めて行動している。

時間割を決めるなんてしっかりしてるな、と思う人がいるかもしれないが、以下の本によるとそれは逆で、自分でタイムマネジメントが出来ない人こそ時間割を決めた方がよいとのこと。

強く生きるノート 考え方しだいで世界は変わる (KEIO MCC Intelligence Series)

強く生きるノート 考え方しだいで世界は変わる (KEIO MCC Intelligence Series)

  • 作者: 本田直之,ちきりん,小池龍之介,平田オリザ,竹中平蔵,原田泳幸,村上憲郎
  • 出版社/メーカー: 講談社
  • 発売日: 2013/11/26
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログ (1件) を見る

で、2/1からなんとなく時間割に沿って行動してみた感想をば。ここで「なんとなく」と書いているのはそこまで厳密に従ってないからである。妻に言わせれば「全然従ってない」ということになるかもしれない。

  • 「◯◯している時間」に◯◯してないと、なんとなくサボっている気分になる
  • サボっている気分から離脱するためにちゃんとやろうとする
  • 時間割を決めていない場合よりも、ダラダラする時間が甘美になる
  • 逆にちゃんと◯◯しておけば休憩時間や自由時間がとても気楽になる
  • 例えば勉強時間でない時間に、意味のない焦燥感に囚われたりすることが少なくなる

というような効果があるようだ。意外に面白い。

2週めでだんだんダレてきたので、時間割を再構築してもいいかもしれない。また、普通の休日などもある程度時間割を切った方がいいかもしれない。と思った。

聞く所によると、さる高名なエンジニアの方は毎日決まった時間に勉強されているそうだ。

JsDocにやさしいJSの書き方

JavaScript

最近、比較的真面目にJsDocを書くという機会があったので。

(※この記事の前提はJsDoc 3.2.2です)

JSで適当に名前空間的なものを切ってコードを書いていくと、

/**
 * @class
/*
function Klass() {
}

Klass.prototype.foo = function () {
};

my.name.space.Klass = Klass;

みたいな書き方がいいか、

/**
 * @class
/*
my.name.space.Klass = function() {
};

my.name.space.Klass.prototype.foo = function() {
};

みたいな書き方がいいか、という割とどうでも良い選択(意味的には同じなので)を迫られることがありますが、これは結論的には後者の方がよくて、

  • 後者だとJsDocが勝手にKlassがmy.name.spaceに属することを判断してdocumentを作ってくれるが、前者の場合は@memberofとか使わないとその辺を理解してくれない
  • 前者だと余計なシンボルがスコープに定義される (Klass)

という二点において、後者を選んだ方がよいです。

ちなみに僕は「メソッド宣言とかを短く書けるから」という理由で前者を選んでいましたが、JsDocを書く段になって後悔しました。

この辺の話は今後JsDocそのものが賢くなると改善されるかもしれませんし、browserifyなどのモダンなモジュールシステム(?)を使っている場合はあまりこういう話題は登場しないかもしれませんね。

JsDocのannotationを真面目に書くのって割と面倒なので、出来るだけannotationなしでJsDocに構造を理解してもらえるようにコード書いたほうが後々ラクですよ、というお話でした。

Googleは内部的には違うものを使っていると思いますが、JsDocの書き方自体はclosure libraryが参考になる気がしています。

google/closure-library · GitHub

色々なライブラリが群雄割拠している昨今のJS業界ですが、closure libraryにはGoogleの伝統と知恵が詰まってると思うんだ。多分。

chrome.identity.getAuthTokenで得たaccess tokenをrevokeする

function revokeToken() {
    var token = gapi.auth.getToken()["access_token"];
    chrome.identity.removeCachedAuthToken({ token: token }, function() {});

    var img = new Image();
    img.src = "https://accounts.google.com/o/oauth2/revoke?token=" + token;
}

やること

  • chrome.identityは内部的にaccess tokenをcacheするのでそいつを消さないといけない
  • revokeはRevoke Endpointに投げるだけ

メモ

  • GoogleのOAuth2では、access tokenのrevokeが「認可の取り消し」を意味する。つまり、revokeした後にユーザは再度認可を行う必要がある。
  • 初期起動時に行うGoogle認証・認可のフローをChrome extensionやChrome Apps内でテストしたい場合、上のようなfunctionを用意しておいてUIなりdev consoleなりから叩けるようにしておくと便利

初めて真面目にChrome extension作ったのでチラ裏メモ

JavaScript Chrome

まだ公開してないけどね。

  • デスクトップ自体のアイドル(ユーザ操作がない)状態やロック状態はchrome.idleで取れる。ユーザ操作がないと判断するまでのtimeoutも自分で決められる。最短15sec。
  • Chrome自体からフォーカスが離れたかどうかはchrome.windows使って判定すればオーケー (chrome.app.windowではない)
  • 参考: Detect browser focus/out-of-focus via Google Chrome Extension - Stack Overflow (厳密に言うとonFocusChangedのコールバックに渡ってくるのはwindowではなくwindowIdなのでこのコードは間違っている)
  • chrome.sendMessageとかmessagePort系とかの機能はchrome.storage.onChangedで代用できないこともないが、storageを使うのは永続化したいデータのみに留めておいた方が無難だろう
  • chrome.browserAction.setPopupで右上ボタンにポップアップを設定するとchrome.browserAction.onClickedが効かなくなるが、そこはpopup内のjsからbackground pageに対してchrome.runtime.connectし、chrome.runtime.onConnectedをシグナルにして処理すれば問題ない
  • もちろんchrome.runtime.onConnectedはclick eventの代替ではないが、どうせpopupとbackground pageの間でメッセージングするんでしょうと。
  • popupのhtmlの中にanchorがあるとChromeが勝手にfocusしてうざい場合はanchor elementにtabindex="-1"を指定する。ってもうちょっとマシな方法ないんかい。(http://stackoverflow.com/questions/16701082/chrome-extension-first-link-is-auto-focused-in-popup)
  • Chrome extensionの中でgapi (いわゆるGoogle系APIのJSライブラリ)をOAuth2の認可通した上で使いたい場合は chrome.identity.getAuthTokenしてのち得られたtokenを gapi.auth.setToken({ access_token: token }); すればよい
  • 読み込み方はこんな感じで (http://stackoverflow.com/questions/18681803/loading-google-api-javascript-client-library-into-chrome-extension)
  • chrome.i18nは普通に使える、それ以上でも以下でもない

総じて、extension開発は、クロスブラウザとか気にせずバリバリ色んな機能を使えるので気持ちがいい。情弱なのでdialog elementとか初めて使った。こういうのがちゃんと使えると、ダイロアグ的なものを出すためだけにUI系のライブラリを入れる必要がなくなるのでうれしい。

あとVue.js割と使いやすかった。小規模なコードだから足りない部分が気にならないだけなのかもだけど。