Meteorのあんちょこ꒰｡･ω･`;꒱

# 本記事について

- 本記事は、「 [体感！JavaScriptで超速アプリケーション開発 －Meteor完全解説](http://gihyo.jp/dev/serial/01/meteor)（Meteor version 0.3.6）」の内容を、1.3.4に置き換えた時のメモです。
- それに加えて、MeteorでのルーティングやらReactやら興味のあるものを記述しています。
- 筆者は、WEB専業ではありませんし、感覚的に理解することにまず重きを置いております。間違いがありましたら、コメント頂けると助かります。お手柔らかにお願いいたします。

----

# What is Meteor?

 [Introduction @ Meteor Guide](https://guide.meteor.com/index.html)の要約...

- モダンウェブ＆モバイルアプリを開発するための、**フルスタック（全部入り）JSプラットフォーム** 
- **リアクティブアプリケーション**作成可能（相互反応的なアプリケーション、はたまた、同時編集とか？）
- Javascript（Node.js含む）で基本的には記述。
- （CSS、HTML、Reactの場合はJSX等の知識が必要。）

- リアクティブの定義がわからなかったので、「[リアクティブプログラミングへの理解がイマイチだったのでまとめてみた @ UUUM攻殻機動隊](http://system.blog.uuum.jp/entry/%E3%83%AA%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%B8%E3%81%AE%E7%90%86%E8%A7%A3%E3%81%8C%E3%82%A4%E3%83%9E%E3%82%A4%E3%83%81%E3%81%A0%E3%81%A3)」を読んだ。

# 参考文献

- 公式
    - [Meteor Tutorial](https://www.meteor.com/tutorials)
    - [Meteor Guide](https://guide.meteor.com/)
- 解説
    - [Meteor Fan (日本語情報)](http://meteor-fan.axlight.com/meteor-tutorial-blaze/)
    - [体感！JavaScriptで超速アプリケーション開発 －Meteor完全解説](http://gihyo.jp/dev/serial/01/meteor)

# サンプル

- [Sample Git Repository](https://bitbucket.org/shoko_kb_study/meteor/overview)

----
 
# インストール

- 実行ファイル：/usr/local/bin/meteor
- [Meteorをインストールしよう：Meteor Fan (日本語情報)
](http://meteor-fan.axlight.com/install-meteor/)

```bash:console
# 最新 2016/11/06
$ curl https://install.meteor.com/ | sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  7784    0  7784    0     0   7557      0 --:--:--  0:00:01 --:--:--  7564
Downloading Meteor distribution
######################################################################## 100.0%

Meteor 1.4.2 has been installed in your home directory (~/.meteor).
Writing a launcher script to /usr/local/bin/meteor for your convenience.
This may prompt for your password.
Password:

To get started fast:

  $ meteor create ~/my_cool_app
  $ cd ~/my_cool_app
  $ meteor

Or see the docs at:

  docs.meteor.com

$ meteor --version
Meteor 1.4.1.2 

# ----
# 旧バージョン
$ curl install.meteor.com | /bin/sh

#----
# バージョン確認
$ meteor --version
Meteor 1.3.4.1
$ meteor --help
Usage: meteor [--release <release>] [--help] <command> [args]
       meteor help <command>
       meteor [--version] [--arch]

With no arguments, 'meteor' runs the project in the current
directory in local development mode. You can run it from the root
directory of the project or from any subdirectory.

Use 'meteor create <path>' to create a new Meteor project.

Commands:
   run                [default] Run this project in local 
    :

See 'meteor help <command>' for details on a command.
```

----

# Hello Project

## プロジェクト作成

```bash:console
$ meteor create hello
```

## 実行（meteor）

```bash:console
$ cd hello
$ meteor
=> App running at: http://localhost:3000/
```

- [http://localhost:3000/](http://localhost:3000/)で動作を確認する。
- 終了は「Ctrl+C」でできる。

### 別のポートを使用したい場合

- "meteor"代わりに、"meteor run"でポートを指定できる。

```bash:console
$ meteor run --port 3030
```

### 公式サンプルの実行

- シンプルなTODOアプリ。
- 同期編集できることが確認出来る。
- （wordplayがないため、simple-todosを使用。）

```bash:console
$ meteor create --example simple-todos
To create the simple-todos example, please run:
  git clone https://github.com/meteor/simple-todos
$ git clone https://github.com/meteor/simple-todos
```

## デバッグプリント

- console.log(...)（☆）でデバッグプリント可。
- サーバ側のコードは「meteor」コマンドを叩いたコンソールに表示される。
- クライアント側のコードは、ブラウザのコンソール（Chromeの場合は、「表示」→「開発／管理」→「デベロッパーツール」のConsole）に表示される。

```js:hello/client/main.js
Template.hello.events({
  'click button'(event, instance) {
    // increment the counter when button is clicked
    instance.counter.set(instance.counter.get() + 1);
    // ☆コンソール表示 
    console.log("You pressed the button.");
  },
});
```

## リロード不要で編集可

- サーバを動かしたまま、編集すると、変更が反映される。（リロード不要）

```html:hello/client/main.html
  <h1>Welcome to Meteor!</h1>
  <!--日本語でヘッダを追加してみる-->
  <h1>Meteorにようこそ</h1>
```

# ディレクトリ構造

- JavaScriptファイルは、「サーバでもクライアントでも実行される」
- **clientディレクトリ**...client-side javascipt
    - クライアント側で実行されるJavaScript・CSS・HTMLファイルを格納。
    - if(**Meteor.isClient**){}の分岐ブロックで定義するのと同等。
- **serverディレクトリ**...server-side javascript
    - サーバ側で実行されるJavaScriptを格納。
    - if(**Meteor.isServer**){}の分岐ブロックで定義するのと同等。
- **publicディレクトリ**...static javascript
    - 静的なファイル（画像など）を格納。
    - このディレクトリ内のファイルはMeteorによって特別な処理を行われることなく、「そのまま」静的ファイルとして配信。
    - このフォルダに登録したファイルはルートパスからアクセスできる。
        - 例えば、public/images/sample.pngとして保存した場合、(localhost:3000)/images/sample.pngでアクセスできる。

## HTML

- server & public以外に配置のHTMLは１つのHTMLに結合される。
- 結合順は深さ優先＆アルファベット順となる。
- テンプレート言語は**Spacebars**というHandlebarsに類似したもの。
- それ以外のJavaScriptTemplate「[mquandalle:**jade**](https://atmospherejs.com/mquandalle/jade)」とかもOKらしいが、疑う余地もなく、Spacebarsを覚えることとする。
- [Understanding Spacebars @ Meteor Capture](http://meteorcapture.com/spacebars/)

## スタイルシート

- serverディレクトリ以外に配置。
- CSSファイルは、HTMLに<link>で自動的に取り込まれる。
- CSS　プリプロフェッサーとしては、Sass、Less.js、Stylusを使用できる。

----

# JQuery

- デフォルトで使用可。（デフォルトでパッケージファイルにjqueryが追加されている。）

```text:.meteor/packages
jquery                  # Helpful client-side library
```

```html:client/main.html
<template name="hello">
  <!--こちらは反応-->
  <button id="alert">Alert</button>
  <!--こちらは無反応-->
  <button id="no_alert">No_Alert</button>
</template>
```

```js:client/main.js
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';

import './main.html';

Template.hello.events({
	// JQueryが使える。
	'click #alert'(event, instance) {
		alert("clicked sample");
		console.log(instance);
		console.log(instance.$('button#alert'));
		console.log(instance.$('button#alert').text());
	},
});
```

# Call Server-side Function

- クライアントからサーバサイド関数を呼出する。

```html:client/main.html
<template name="hello">
  <button id="console">Click Me</button><br/>
  姓<input id="lastname"/>　名<input id="firstname"/><button id="show">ダイアログ表示</button>
</template>
```

```js:client/main.js
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';

import './main.html';

Meteor.startup(() => {
	// サーバサイド関数を呼び出す。
 	$('#show').on('click', function (){
 		var firstname = $('#firstname').val();
 		var lastname = $('#lastname').val();
	 	Meteor.call('hello', firstname, lastname, function(err, result) {
  			// callback
  			alert(result);
		});
 		
 	});
});

Template.hello.events({
	'click #console'(event, instance) {

		// 可変引数で引数を渡して、callする。
  		Meteor.call('hello', 'Shoko', 'CALL', function(err, result) {
  			// callback
  			console.log(result);
		});

  		// 配列で引数を渡して、callする。
  		Meteor.apply('hello', ['Shoko', 'APPLY'], function (err, result) {
  			// callback
  			console.log(result);
  		});
  	},
});
```

# テンプレート
- [Meteorのあんちょこ꒰｡･ω･`;꒱ テンプレート](http://qiita.com/shoko_kb/items/0c193b42fa22c302090e)
- Handlebarsに類似した[Spacebars](https://docs.meteor.com/packages/spacebars.html)を使用する。
- とりあえず、次を覚えておく。
    - Template.TEMP_NAME.helpers({});はテンプレートのデータ＆関数を定義
    - Template.TEMP_NAME.events({});はテンプレートのイベントを定義

# データベース接続

- [Meteorのあんちょこ꒰｡･ω･`;꒱ データベースアーキテクチャ](http://qiita.com/shoko_kb/items/486645835293aac393a0)
- MongoDBにデータストアできる。
- DBデータは、キャッシュとして展開され、キャッシュは全サーバ＆全クライアントで同期される。→リアクティブプログラミング（共同編集等）が可能。
- バックパップ＆リストアについてもこちら。

# Reactive-Dict

- [Meteorのあんちょこ꒰｡･ω･`;꒱ Reactive-Dict](http://qiita.com/shoko_kb/items/94648387ddca68e9601d)
- クライアントUI状態をリアクティブディレクトリに保存する

# アカウント管理

- [Meteorのあんちょこ꒰｡･ω･`;꒱ アカウント管理](http://qiita.com/shoko_kb/items/abd0f910aebea2739f2f)
- Username & Password形式、facebook、googleなどの認証が手軽にできる。

# Route（kadira:flow-router）

- [Meteorのあんちょこ꒰｡･ω･`;꒱ Routes（kadira:flow-router）](http://qiita.com/shoko_kb/items/73bf9291ef27f93f85a3)

# React（simple-todos）

- [Meteorのあんちょこ꒰｡･ω･`;꒱ ReactJS](http://qiita.com/shoko_kb/items/321b550429e4654901a6)
- VirtualDOMを使用し、DOM操作を高速化できる。

----

# 派生言語系

## TypeScript

- [Typescript compiler for Meteor.js - GitHub](https://github.com/meteor-typescript/meteor-typescript-compiler)

## ~~CoffeeScript~~

- ~~[Meteorのあんちょこ꒰｡･ω･`;꒱ CoffeeScript編](http://qiita.com/shoko_kb/private/121a744239b4754d257b)...古い？~~
- ECMAScriptで記述するのが主流らしい。

----

# ファイルのアップロード

- [CollectionFS/Meteor-CollectionFS](https://github.com/CollectionFS/Meteor-CollectionFS)が利用可。（他にもいくつかあるようだけど。。。）
- 下記にアップロードできるらしい。
    - MongoのGridFS
    - ファイルシステム（NASに保存できるかは微妙？）
    - AWS S3
    - Dripbox
    - Alibaba系のストレージ
- [How to upload files with Meteor.js?](https://medium.com/@victorleungtw/how-to-upload-files-with-meteor-js-7b8e811510fa)がわかりやすそうだった。

## Cannot find module '../build/Release/bson'への対策

```bash:console
$ meteor
[[[[[ ~/sync-emr2/sync-emr ]]]]]              

=> Started proxy.                             
=> A patch (Meteor 1.5.4) for your current release is available!
   Update this project now with 'meteor update --patch'.
=> Started MongoDB.                           
I20171113-21:57:19.492(9)? { [Error: Cannot find module '../build/Release/bson'] code: 'MODULE_NOT_FOUND' }
W20171113-21:57:19.549(9)? (STDERR) js-bson: Failed to load c++ bson extension, using pure JS version
I20171113-21:57:19.914(9)? services.init
=> Started your app.

=> App running at: http://localhost:3000/
```

```js:.meteor/local/build/programs/server/npm/node_modules/meteor/cfs_gridfs/node_modules/mongodb/node_modules/bson/ext/index.js
try {
	// Load the precompiled win32 binary
	if(process.platform == "win32" && process.arch == "x64") {
	  bson = require('./win32/x64/bson');
	} else if(process.platform == "win32" && process.arch == "ia32") {
	  bson = require('./win32/ia32/bson');
	} else {
	  bson = require('../build/Release/bson');
	}
} catch(err) {
	// Attempt to load the release bson version
	try {
          // bsonの参照先をへのう
	  // bson = require('../build/Release/bson');
	  bson = require('../browser_build/bson');
	} catch (err) {
		console.dir(err)
		console.error("js-bson: Failed to load c++ bson extension, using pure JS version");
		bson = require('../lib/bson/bson');
	}
}
```

----

# デプロイ

- [Meteorのあんちょこ꒰｡･ω･`;꒱ デプロイ編](http://qiita.com/shoko_kb/items/135da2cab3b88aca5cae)

----

# Meteor本体のアップデート

- **meteor update**というコマンドで最新版のMeteorが使用できる。

```bash:console
=> Meteor 1.4 is available. Update this project with 'meteor update'.

# 指定のバージョンにアップデート
$ meteor update --release 1.5.4
```