「Meteor」と一致するもの

Meteorには様々な便利パッケージがありますが、 その中でもうまく使えばだいぶコーディングを省けるパッケージを紹介します。 autoformはフォームを生成するためのパッケージです。 MongoDBのスキーマを定義しバリデーションするsimple-schema とともに使います。 collection2とも使えます。 今回はsimple-schemaで説明します。

初めに、パッケージのインストールは、

meteor add aldeed:simple-schema aldeed:autoform check

です。バリデーション用のcheckパッケージも入れました。

例えば、毎日の体重を記録するアプリを想定しましょう。 コレクションの定義は、

Records = new Mongo.Collection('Records');

となります。これのスキーマを定義するには、

RecordSchema = new SimpleSchema({
  date: {
    type: Date
  },
  weight: {
    type: Number
  }
});

のようにします。この例は単純ですので直感的と思いますが、より詳しくはsimple-schemaのドキュメントを参照ください。

さて、このスキーマを使ってフォームを作成するには、

<template name="inputForm">
  {{> quickForm id="inputForm" schema="RecordSchema" type="method" meteormethod="/records/insert"}}
</template>

とします。これにより、

autoform_scn.png

このような感じでフォームが完成しました。このフォームはtypeに合わせて適切なコンポーネントが使用されている上、値が入力されていなかったり不適切な場合はアラートメッセージを表示してくれます。

フォームがsubmitされた際にはmeteor methodsが呼び出されます。この実装は例えば下記のようになります。

Meteor.methods({
  '/records/insert': function(doc) {
    check(doc, RecordSchema);
    Records.insert(doc);
  }
});

このcheckが重要で、これがないと不正なデータを登録できてしまいます。フォームのバリデーションはクライアントサイドだけの話なので。 このcheckすら冗長だと考える方はcollection2を使ってみるとよいでしょう。

autoformの最も簡単な紹介でした。これ以外にも色々柔軟な使い方ができるので、おすすめのパッケージです。

最後に全体のコードを載せておきます。これだけですので、まずは試してみるとよいでしょう。


HTMLファイル

<body>
  {{> inputForm}}
</body>

<template name="inputForm">
  {{> quickForm id="inputForm" schema="RecordSchema" type="method" meteormethod="/records/insert"}}
</template>

JavaScriptファイル

Records = new Mongo.Collection('Records');
RecordSchema = new SimpleSchema({
  date: {
    type: Date
  },
  weight: {
    type: Number
  }
});

Meteor.methods({
  '/records/insert': function(doc) {
    check(doc, RecordSchema);
    Records.insert(doc);
  }
});

Meteor 1.2からはAngularとReactのサポートも追加されましたが、Blazeも根強い人気があります。今回はそんなBlazeをちょっと使いやすくするパッケージを二つ紹介します。

初めに紹介するパッケージは、Handlebar-helpersです。

インストールは、

meteor add raix:handlebar-helpers

です。これを使うと、テンプレートで、

{{#if $lt counter 10}}

のようなことが書けるようになります。実は本来テンプレートにはロジックを書くのはよろしくないので、これはあまり好まれない場合があります。しかし、通常の書き方だと、

{{#if isCounterLargerThanTen}}

のようになりヘルパー関数を用意する必要があります。よって、小規模プロジェクトなどでは原則を破ってロジックを書いてしまった方が効率がよい場合もあると思います。

次に紹介するパッケージは、blaze-magic-eventsです。

インストールは、

meteor add themeteorites:blaze-magic-events

です。これも好みが分かれるところですが、イベントハンドラを書きやすくするものです。テンプレートに、

<button onclick={{sayHi}}>Say Hi!</button>

と書いて、JavaScriptコードに、

Template.helloworld.events({
  sayHi (event, template) {
    console.log('event and templateInstance params', event, template)
    template.$('p').html('hi there from sayHi() handler!')
  }
});

と書きます。これも微妙にロジックを書いてしまっているので美しくないのですが、jQueryに慣れている人は分かりやすいかもしれません。

最後にせっかくなので、自分のパッケージも紹介しておきます。blaze-showhideです。これもテンプレートに簡単なロジックを書いて表示・非表示を切り替えるようにするものです。

以上、テンプレートにはロジックを書かないという原則を破ってちょっと便利にするパッケージの紹介でした。

以前、Angular向けに自分で開発したsocial-cms-backendは今もメンテナンスしていますが、 これのMeteor版があったら面白いだろうなと思っていました。Meteor版だとfrontendも含まれるので、単にsocial-cmsと呼ぶものになるかなとか。 既に、似たようなものが既にあったので紹介します。自分で作る手間は省けたものの、作ってみたかったという気持ちもあったりします。

一つは、ryw:blog (GitHub)です。 これは他のアプリに組み込むライブラリとしての位置付けで作られたもので、 なんとiron-routerとflow-router両方に対応しているということです。 単体で動かそうと思うと、意外とパッケージ導入に手間がかかりました。 参考までに手順をまとめておきます。

meteor create test-app
cd test-app
meteor add ryw:blog
meteor add kadira:flow-router kadira:blaze-layout
meteor add twbs:bootstrap ian:accounts-ui-bootstrap-3
meteor add accounts-password
meteor run

その後、htmlにログインボタンを設置すれば一応動きます。 ただし、デフォルトでは全員管理者になってしまうので、ロール管理しようとするともう少し複雑になります。 accounts-admin-ui-bootstrap-3 を使うとよさそうですが、初期の管理者を手動で設定する必要があったりと多少導入にハードルを感じます。 もっと簡単にスタンドアローンで動かすための整備は、まだ残件かなと思いました。

UIはいろいろカスタマイズできるようになっているようですが、コメント機能がないのは不完全な感じがします。 DISQUSを使う方法が説明されていますが、スタンドアローンで機能拡張できるとよいです。 そういう意味では、ライブラリとして使うものなのか、すぐに使えるようにするものなのかが曖昧に感じてきました。 このあたりもう少しいじってみたいような気もします。

さて、ついでにもう一つのパッケージを紹介します。 xolvio:md-blog (GitHub)です。 これは、The Meteor Testing Manualで実際に使われているアプリのパッケージのようです。 こちらにデモサイトがあるので様子が分かります。 表示のカスタマイズやロールの設定もできるようです。 試してはいませんが、スタンドアローンで動くアプリを作るのが目的であればこちらの方が楽かもしれません。

感想ですが、だいぶ便利なものが作られているなと思う一方で、まだまだ色々登場しそうですし、何か作ってみたいなと思います。

MeteorでGoogle Mapsを使うライブラリとしては、 dburles:google-maps が有名なようですが、使ってみたところちょっと気に入りませんでした。 せっかくBlazeがシンプルな設計になっているのに、全然お手軽な感じがしません。 リアクティブにするためのサンプルが載っていますが、アプリ開発者の仕事になってしまっています。 慣れている人はいいですが、Blaze初心者にはつらい感じです。

ないものは作ろうということで、作りました。

https://atmospherejs.com/daishi/blaze-google-maps

全部のAPIをサポートしているわけではないので、ライブラリとして置き換えられるようなものではありません。 しかし、マーカーをコレクションから読み込んで表示することに限れば、素直に使えるのではないかと思います。 もちろん、リアクティブに動作します。

Google Maps APIをMeteorから使ってみようと思う方はぜひお試しください。


10/6追記

なぜか「ライブラリ」と書いていましたが「パッケージ」と書くつもりでした。

Meteorの標準テンプレートであるBlazeはシンプルで割と気に入っています。 最低限の機能が用意されていて、あとは自分でがんばってねという感じが悪くないです。 ただ、Angularに慣れてしまうとこんなことはできないのかなどと思うことがあります。

その一つが、ng-showみたいなこと。ng-clickと合わせて表示を切り替えることがしばしばあります。

Blazeでは{{#if}}を使うと似たようなことができます。これはおそらくng-if相当です。具体的には次のようになります。

<template name="foo">
  {{#if hello}}
    <p>Hello World!</p>
  {{/if}
</template>

と

Template.foo.helpers({
  hello: function() {
    return Session.get('hello');
  }
});

さらに表示を切り替えるボタンは例えば次のようになります。

<template name="bar">
  <button>Toggle</button>
</template>

と

Template.bar.events({
  'click button': function(event) {
    event.preventDefault();
    Session.set('hello', !Session.get('hello'));
  }
});

ちなみに、AngularだとHTML内にロジックを書いてしまえば次のように書けます。

<p ng-if="hello">Hello World!</p>
<button ng-click="hello = !hello">Toggle</button>

そこで、Blazeでも簡単に書けるようにするパッケージを作ってみました。

https://atmospherejs.com/daishi/blaze-showhide

これを使うと、

<div>
  {{#showIf name="hello"}}
    <p>Hello World!</p>
  {{/showIf}}
  {{#toggleShowHide name="hello"}}
    <button>Toggle</button>
  {{/toggleShowHide}}
</div>

こんな感じで書けるようになります。Sessionはアプリで共通なので実際に使う場合は他のtemplateと競合しないように注意する必要があります。

ng-ifやng-showを使いたいのならangular-meteorを使えばよいのではないかという意見もありますが、それはそれとしてBlazeでもパッケージでこういうやり方ができるということが分かりました。

余力があればやってみたいことは、ng-show相当の機能や設定のカスタマイズなどです。 余力というかモチベーションですが。

ところで、既に似たような機能を持つパッケージがないか探したのですが、見つかりませんでした。 もしかしたら、探し方が不十分であるパッケージの一機能として実現されているものもあるかもしれません。 いずれにしてもパッケージ作りの勉強になりました。

最近、Meteorの勉強中です。何かパッケージを作ってみたいと思ったのですが、多くのものはすでに誰かがやっています。 MeteorのパッケージはAtmosphereで探します。

今回、自分が使おうと思ったものにぴったりのものが見つからなかったので、作ってみました。 探したものはFacebookのAPIを呼び出すライブラリです。OAuthのライブラリはMeteorで提供されているのですが、Graph APIを使うものは3rt partyのものを探しことになります。

見つけたのはこれらです。

  • biasport:facebook-sdk mrt時代からあるパッケージでインストール数も多いです。ドキュメントを見るとクライアントライブラリのようです。
  • stevezhu:fbgraph fbgraphをラップしたパッケージです。サーバサイドのみで動きます。
  • mrt:facebook-sdk これがオリジナルっぽいですね。
  • jdrorrer:facebook-sdk
  • dcsan:facebook-sdk
  • dferber:graph-api
  • maxkferg:facebook-collections 少し趣向が変わった感じでおもしろそうです。クライアントから使うことがメイン。
  • borges:facebook-sdk
  • timbroddin:facebook-node-sdk ドキュメントがないのでどういうものか分からず。

いっぱいあるように見えますが、facebook-node-sdkはGitHubを見るとforkしているのが分かります。

https://github.com/jdrorrer/facebook-sdk/ ← https://github.com/dcsan/facebook-sdk ← https://github.com/biasport/facebook-sdk ← https://github.com/hugesuccess/facebook-sdk

ネットワーク図を見てもいいかもしれません。全部は表示されていないようですが。

さて、今回はサーバサイドのライブラリを探していたのでfbgraphとgraph-apiが候補なのですが、過去の検討で使っていたライブラリを使いたいという要求もありました。 そこで、そのライブラリをMeteorパッケージにラップしました。

作ったパッケージは、 https://atmospherejs.com/daishi/facebook-server-api です。

ソースコードは、GitHubにあります。 中身はなんと2行だけです。

一応、新規にFB.mapiというAPIを用意しました。Meteor流のfibersを使った同期的APIです。

fibersはあまり好まないのですが、Meteorでやっていくには仕方ないかと諦め気味です。

node.jsのデプロイ先としてはherokuを使うことが多いのですが、 他にはどういう候補があるのか調べてみようと思いました。 昔の記事を見ると手軽に使えそうだった、Nodejitsu, AppFog, Node Ninjaなど 使えなくなった(もしくは、以前より使いにくくなった)ものもあります。 また、最近Ghostを試してみたいと思ったのですが、 herokuがサポートされていない(ファイルアクセスができない)こともあり、 他の候補を調べてみることにしました。

条件は、無料で使えるプランがある(一定期間でも)ことです。 網羅はできていないと思います。順不同です。 実際に試したわけではなく、サイトから得られる情報をまとめただけです。

flow.ch

Flow App Engineは、Java, PHP, Ruby, Node.js, Python or .NET (Beta) を動作させることができて、dockerのイメージも動かせるそうです。 各種データベースも用意されているとのこと。 webベースのdashboardで簡単に操作できるようです。

free trialは14日間です。pricingは、usage-basedとfixedの2種類とのこと。

modulus.io

Modulusは、Node.js,PHP, Javaが使えます。Meteorがサポートされているのも特徴のようです。 modulusというコマンドをインストールして、デプロイ作業をするようです。 その他必要そうなものはひと通り揃っているように見えます。

sign upすると30日間使える$15分のクレジットがもらえるようです。 しかし、一番安い構成でも月に$28.80になるので、30日連続運用はできないことになります。

dotCloud

dotCloudは、Python, Java, Node.js, PHPが使えるようです。 デフォルトはMySQLですが、他のストレージのadd-onもあります。MongoDBもMongoSoupというのがあるようです。 特徴的なのは、プラットフォームへのアクセスで、 CLIのツールと、Webコンソールと、REST APIが用意されているとのこと。

Sign up for Freeとありますが、実際無料でどこまで使えるか分かりませんでした。 一番小さい構成では、月$9.90のようです。

cloud.google.com

Google Cloud Platformは、IaaSに近い感じですが、 Cloud Launcherを使って簡単にStackを構成できるようです。MEANも使えるようです。

Free trialでは、$300分を60日間使えるそうです。

bluemix

IBM Bluemixは、OSSのCloud FoundryをベースとしたPaaSです。 色々使えるようですが、一例として、Node.js, PHP, Python, Rubyがあげられています。

フリートライアルでは、30日間使えるそうです。

現在、アプリ開発コンテストが開催中とのこと。

まとめ

残念ながら、期間限定なしでfreeで使えるサービスは見つけられませんでした。 freemiumは最近は流行りではないのでしょうかね。 herokuもfreeの範囲が狭まることになりましたし、厳しい情勢です。

ng-conf 2015の動画を見ていたら、angular meteor integrationの動画がありました。

https://www.youtube.com/watch?v=uFmf-DeCdEE

Meteorを試した時に、angularを利用する可能性は考えましたし、 そのような記事もどこかで読んだ気がします。 しかし、Meteorが元から持っているテンプレート機能と重複しますし、 Meteorの恩恵をあまり受けられないかと思っていました。

ところが、Angular-Meteorはそれなりにうまく作られているようです。 興味がある方は、チュートリアル を見てみるとよいでしょう。 話が脱線しますが、このチュートリアルとてもやりやすいです。 Meteor本体のチュートリアルもそうですが、チュートリアルなのにかなり本格的な アプリを作っています。 Famo.us universityを見たときも思いましたが、チュートリアル周りの ベストプラクティスがたまってきていますね。 自分でもうまく活用できればいいと思います。

Angular-Meteorのチュートリアルをやってみて一番気に入ったのは、 3-way data bindingです。 これができるということは、AngularFireの代替になるのではないでしょうか。 ちょっとなにか作ってみたくなりました。 逆に一番気になったのは、getReactively周りの処理です。 特に手動でunsubscribeしなければいけないのは面倒です。

Maybe in the future we will add an automatic way to open and close subscriptions in scope's load and destroy events.

とあるので、解決されることを期待します。

話はまた変わりますが、Firebaseのtalkもng-conf 2015にありました。

https://www.youtube.com/watch?v=4nD5fjpIesk

こちらは、本家本流なのですごいですね。v1.0がリリースされたそうです。 彼らが3-way data bindingの名付け親です、たぶん。

Meteorはとても魅力的なのですが、自分が本当に気に入るか分からずちょっと悩んでいます。 その理由は、Fiberを使っていることと、jQueryを使っていること。 callbackは結構好きなのでFiberに魅力をあまり感じません。 一応、Fiberの流儀を使わず、callbackでも書けるので プロジェクトのコーディング規約で気をつければいいのですが。 jQueryの方は、非依存にする話もあるようですが、コアが依存しているという記述もあり、 完全に非依存になるには時間がかかりそうです。

https://groups.google.com/forum/?fromgroups=#!topic/meteor-talk/21y9NbM9v90

別に、jQuery依存だからといって困ることはないのですが、単に気分の問題です。

いずれにしても、Angualr-Meteorにはちょっと興味を持ちました。

LiveReloadをご存知でしょうか。Web開発をするときに、ブラウザのリロードを省く機能を提供するものです。 類似のものとしては、Live.jsというのもあります。 また、Meteorでも実装されています。

一言で言うと、websocketでコネクションを維持して、サーバ側のファイル変更を通知して自動でリロードするものです。 CSSの場合はリロードせずに変更を適用することもできます。 livereloadは商用のようですが、そのコアのソースコードはMITライセンスで公開されています。

livereloadはブラウザ拡張を使うことがメインのようですが、javascript版のクライアントもあります。 javascript版だと、mobile safariでも動きます。 livereloadのnode.js用のサーバは、https://github.com/livereload/livereload-serverで公開されていますが、 これはそのまますぐには使うことができません。 平たく言うとプロトコルが実装されているだけで、実際に更新通知する機能は含まれていません。

そこで、簡単に使えるライブラリとしてまとめてみました。特徴をまとめると、

  • livereloadのサーバコードの最新版を使用(現在npmに登録されているlivereload系のモジュールはほとんど旧バージョン)
  • livereloadのクライアントコードの最新版を使用(npm化されていないのでnapaというモジュールで導入)
  • fs.watch()を使ってファイル変更を迅速に監視(node-watchというモジュールを使用)
  • node-devを使うことでサーバ側のファイル変更を監視して、クライアントを自動リロードする機能を追加
  • これらの機能をたった一行を加えるだけで使えるようにパッケージ化

となります。

プロジェクトページは下記です。

https://github.com/dai-shi/easy-livereload

最低限の使い方は、

app.use(require('easy-livereload')())

ですが、細かい設定はオプションを引数に与えることでできます。

本質的には他人が作ったライブラリを結合して簡単に使えるようにしただけですが、 相当便利だと思いますので、ぜひお試しください。

MeteorでJadeのススメ

  • 投稿日:
  • by

Meteorのお話です。

Node.jsではExpressでよくjadeを使っています。

http://jade-lang.com/

なぜかjadeは好きです。RubyでHamlは使ったことがありますが、それほど好感を持った覚えはありません。なぜでしょう、%があると見栄えが悪いからでしょうか。

Meteorにもjadeのパッケージを作った人がいるようです。

https://atmospherejs.com/mquandalle/jade

これが思いのほか出来がよくて、気に入りました。 単にjadeの変換を再現しただけではなくて、Meteor用にチューンされている感じです。

インストールは、

$  meteor add mquandalle:jade

とするだけで、*.jadeファイルで書けばあとはよろしくやってくれます。上記ページに使い方は書いてありますが、いくつか転記します。

まず、テンプレート呼び出しの

{{> hello}}

は、

+hello

になります。最初はちょっと分かりにくいと思いました。慣れれば普通です。

次に、if文は、

{{if hoge}}
  <div>hello</div>
{{else}}
  <div>bye</div>
{{/if}

が、

+if hoge
  div hello
+else
  div bye

になります。この接頭辞+は省略もできるようですが、個人的には残しておいたほうが制御ブロックであることが見た目で分かりやすくてよいと思いました。else ifも独自実装しているようです。シンタックスシュガーとして。

最後にまだ実装されていないと書いてありますが、anonymous helperというのが載っています。

+if len > 0

みたいなことが書けるようになるそうです。これはとても実装されて欲しい機能です。これだけのためにhelperを書くのは手間でしょう。

以上、Meteorでjadeがすんなり使えるというお話でした。

ついでに、jade系で気になるツールを紹介します。

https://github.com/donpark/html2jade

HTMLをjadeに戻せるようです。まだ試していませんが、 これはいいですね。過去に書いたHTMLをjade化したくなります。 もし安定して使えるなら、人が書いたHTMLを一度jadeにしてから 編集して、再度HTMLに戻すということもできるかもしれません。

さらに、余談ですが、html2jadeを検索していたら、

https://github.com/vidalab/meteor-html2jade

を見つけました。何かと思ったら、html2jadeをwebで使えるようにしたMeteorアプリのようです。