meteorについて
わかってる依存関係
- underscore
- git
meteorのbin (/usr/local/bin/meteor)
やってることは、引数をつけて、meteor.js (僕のmac OSXでは/usr/local/meteor/app/meteor/meteor.js)を実行する
exec "$DEV_BUNDLE/bin/node" "$METEOR" "$@"
以降「$METEOR_HOME=/usr/local/meteor」と読んでください。
meteor.js
$METEOR_HOME/lib/files.js
一番最初にrequireしていて、ファイル操作系のutilを提供してる
- sort
- pre_filter
- file_list_async
- file_list_sync
- is_app_dir
- is_package_dir
- is_package_collection_dir
- find_upwards
- find_app_dir
- add_to_gitignore
- in_checkout
- get_dev_bundle
- get_package_dir
- get_core_dir
- pretty_path
- rm_recursive
- mkdir_p
- cp_r
- mkdtemp
$METEOR_HOME/meteor/deply.js
このファイルの中でdeply先が定義されていて、その他、deploy/delete/mongoの操作が提供されます
var DEPLOY_HOSTNAME = 'deploy.meteor.com'; // (略 exports.deploy_app = deploy_app; exports.delete_app = delete_app; exports.mongo = mongo; exports.logs = logs; exports.run_mongo_shell = run_mongo_shell;
deply_appの中ではbundleメソッドが呼ばれ、tar.gzが作成され、meteor_rpcでdeployされて、その後、tarが削除されます
mongoでは、同じく、meteor_rpcでmongoが呼ばれます。
meteor.jsに戻って
配列Commandsに名前、ヘルプ、関数実装からなる以下のオブジェクトを追加しています
- run / [default] Run this project in local development mode
- help
- create / Create a new project
- update / Upgrade to the latest version of Meteor
- add / Add a package to this project
- remove / Remove a package from this project
- list / List available packages
- bundle / Pack this project up into a tarball
- mongo / Connect to the Mongo database for the specified site
- deploy / Deploy this project to Meteor
- logs / Show logs for specified site
- reset / Reset the project state. Erases the local database.
上記、Commandsを追加したところで、mainメソッドが実行されます。
optimistが使われていて、デフォルトではrunが実行されます。
実際にappを起動するrunメソッド
runメソッドは下記のようになっています。
var app_dir = require_project("run", true); // app or package var bundle_opts = { no_minify: !new_argv.production, symlink_dev_bundle: true }; require('./run.js').run(app_dir, bundle_opts, new_argv.port);
ちょいちょい出てくる
var app_dir = files.find_upwards(files.is_app_dir);
ですが、これは、process.cwd()を起点として、親ディレクトリに登りながら「.meteor/package」のあるディレクトリ、つまり、app_dirを探す処理です。なければpackageを探したりしていますが、省略します。
app_dirが見つかれば、
require('./run.js').run(app_dir, bundle_opts, new_argv.port)
で実行します。
$METEOR_HOME/run.js
meteorでは、portを4つ使用します。
1つは(outer)webapp用で、これをmeteorの起動時にportとして渡します。2つ目は内部用のportでwebapp用+1を、3つ目がwebapp用+2でmongo用に使います。最後がテスト用でwebapp用+3になります。
meteorのリアルタイムを実現している肝がexports.runの内部の下記2つの関数です。
- start_watching
- restart_server
start_proxyでは、httpServerを内向き・外向きで立ち上げ、launchの中では、mongoを立ち上げます。launchの中で一度restart_serverがcallされ、監視が始まります。
start_watching
DependencyWatcherの内部で、fs.watchが実行され、各種meteorのファイルおよびappのファイルが監視対象となります。
変更があった際には、restart_serverが呼び出されることで、リアルタイムな変更を可能にしています。
まとめ
駆け足でしたが、リアルタイムを実現する仕組みを含めて、meteorの内部を調べてみました。
このあとは、coffeeやlessを含めてbundle周りをもう少し見てみたいと思います。