ここに概要の簡単な表があります。以下でいくつかのことについて説明します。
+-------------------------------------+------------------------- ---+------------------------------------+
| | | | 鉄道JS | タワー.js |
+-------------------------------------+------------------------- ---+------------------------------------+
| | 最初のコミット | 2011年1月 | 2011年10月 |
| | レール | 2.3.x | 3.x |
| | Node.js | >= 0.4.x | >= 0.4.x |
| | サーバー | ✓ | ✓ |
| | クライアント | クライアント | | | ✓ |
| | テンプレートにとらわれない | ✓ | ✓ |
| | デフォルトのエンジン | EJS | コーヒーカップ |
| | データベースに依存しない | ✓ | ✓ |
| | デフォルトのデータストア | モンゴDB | モンゴDB |
| | モデルの検証 | validatesPresenceOf('メール') | validates('email', プレゼンス: true) |
| | クエリ スコープ | ✓ | ✓ |
| | 連鎖可能なスコープ | | | ✓ |
| | パラメータ解析 | | | ✓ |
| | コントローラー | ✓ | ✓ |
| | リソース コントローラー | | | ✓ |
| | ファイルの命名 | users_controller.js | usersController.coffee |
| | vm.runInCustomContext | ✓ | | |
| | アセット パイプライン | | | ✓ |
| | 資産圧縮 | | | ✓ |
| | ルーティング | map.resources('投稿') | @resources '投稿' |
| | ネストされたルート | ✓ | ✓ |
| | 生成された URL ヘルパー | ✓ | | |
| | ジェネレーター | ✓ | ✓ |
| | コマンドライン API | ✓ | ✓ |
| | REPL (コンソール) | ✓ | ✓ |
| | CoffeeScript コンソール | | | ✓ |
| | アセットのキャッシュ方法 | タイムスタンプ | MD5 ハッシュ |
| | プロダクション アセット パス | /app.css?123123123 | /app-859c828c89288hc8918741.css |
| | 優先言語 | JavaScript | コーヒースクリプト |
| | CoffeeScript のサポート | ✓ | ✓ |
| | 国際化 | ✓ | ✓ |
| | Heroku サポート | ✓ | ✓ |
| | ストリングケース | スネークケース | キャメルケース |
| | フォームビルダー | ✓ | ✓ |
| | セマンティック フォーム ビルダー | | | ✓ |
| | テーブルビルダー | | | ✓ |
| | ファイルウォッチャー API | | | ✓ |
| | アセットのライブリロード | | | ✓ |
| | テスト スイート | | | ✓ |
| | テスト用ジェネレーター | | | ✓ |
| | Twitter ブートストラップ | ✓ | ✓ |
| | HTML5 ボイラープレート | | | ✓ |
+-------------------------------------+------------------------- ---+------------------------------------+
既存のフレームワークでは十分に達成できなかったいくつかの目標を達成するために、私は Tower.js を作成しました。ここにそれらの目標のいくつかがあります。
1. クライアントとサーバーで同じコード
Node.js によってサーバー上で JavaScript が可能になったので、アプリケーションの一部を Rails で作成し、別の部分を Backbone で作成する理由はありません。それはDRYではありません。モデルを一度定義すれば、クライアントとサーバーの両方で使用できるはずです。
RailwayJS は Express を中心に構築されているため、サーバー上でのみ動作します。Tower.js も Express を中心に構築されていますが、クライアントとサーバーの両方で機能するようになっています。Tower.js は、クライアントとサーバーにまったく同じ API を提供します。これは、クライアントとサーバーで同じように機能するように、ルーターのようなものを書き直さなければならなかったことを意味します (さらに、同じルート セットを使用history.pushState
して、#
フォールバックでのようなことを行うことができます)。
2. クライアントとサーバーで同じ「ビュー」
Rails と Haml テンプレートの作成に多くの時間を費やしました。並行して、Mustache などのテンプレート言語を使用して Web およびモバイル JavaScript インターフェースを作成していました。それはコードの重複です... クライアント (JavaScript テンプレートとして) とサーバー (静的 HTML のレンダリング) の両方で同じビュー/テンプレートのセットを使用できるはずです。
Haml は非常に優れていたため (非常にクリーンで、任意の Ruby を実行でき、pretty-printing が組み込まれているなど)、最も近い JavaScript の代替はCoffeeKup でした。また、クライアントとサーバーの両方で機能します。CoffeeKup を使用すると、JavaScript のすべての機能を使用してテンプレートを作成できるため、制限はありません。Mustache で FormBuilder を構築するには、多くの作業または多くのコード、あるいはその両方が必要になります。
ただし、テンプレート エンジンを自由に交換して、クライアントまたはサーバーに Jade、Mustache、Handlebars などを自由に使用できることに注意してください。CoffeeKup はクリーンで強力なデフォルトです。
3. クライアントとサーバーでの Rails 品質のモデル API
ActiveModel (ActiveRecord for SQL と MongoDB for Rails の Mongoid によって実装されています) は、開発者がデータを定義して操作できるようにする、非常に完全で十分にテストされた API です。パワフルで楽しいです。以前の (および現在の) JavaScript 実装はすべて、これほど堅牢で適切に設計されたものではなく、近い将来に何かが起こるとは思いませんでした。
これをRailsで書くことができれば:
User.where(:email => /[a-z/).page(2).limit(20)
JavaScript でそれを行うことができるはずです。
App.User.where(email: /[a-z/).page(2).limit(20)
Tower.js には「連鎖可能なスコープ」が付属しています。これは、ハードコア クエリ + ページネーションを意味します。これはMongoDB クエリ APIをモデルにしていますが、この API の「入力」は、さまざまなデータストアに適したデータベース コマンドに変換されます。
4. SQL および NoSQL データストアへの統一インターフェース
現在、Tower.js には MongoDB と Memory (ブラウザー内) ストアがあり、その他の一般的なデータベース (CouchDB、Neo4j、PostGreSQL、MySQL、SQLite、Cassandra など) に統一されたインターフェイスを提供することを目的としています。
RailwayJS も JugglingDB を介してこれを行っているようで、良いスタートのようです。しかし、私はいくつかの理由でそれを使用しないことにしました。まず、Rails 2.x API ( User.validatesUniquenessOf "email"
vs. User.validates "email", presence: true
) を中心に構築されているようです。第 2 に、Rails 3 のようにチェイン可能なクエリが豊富ではありません。3 番目に、コードをコードベースにすばやく追加できるようにしたいのですが、私は非常にうるさいので、CoffeeScript を使用するように全体をリファクタリングすることになるでしょう (笑)。また、クライアントでも機能する必要があるため、その周りにレイヤーを構築したくありません。そのため、ライブラリ アーキテクチャを可能な限り最小限に保つことが最優先事項です。
5.機知に富んだコントローラー
inherited_resources Ruby gemは、Rails コントローラーからコードの約 90% を切り取りました。7 つの基本的なコントローラー アクションを実装するための一連の規則を考え出しました。Tower.js にはこのようなものが含まれているため、デフォルトではコントローラーにコードを記述する必要はなく、コントローラーは引き続き JSON と HTML で応答します。また、ネストされたルートを定義できるようにします。
6. URL からデータベースへの自動クエリ パーサー
Tower.js では、URL 内の特定のパラメーターを監視するようにコントローラーに指示できます。コントローラーはそれらをモデル クエリに適用できるハッシュに変換します。
class App.UsersController extends App.ApplicationController
@param "email"
index: ->
App.User.where(@criteria()).all (error, users) =>
@respondTo (format) =>
format.json => @render json: users
format.html => @render "index", locals: {users}
のような URL を指定すると/users?email=abc&something=random
、@criteria()
ハッシュが得られます{email: /abc/}
。
Railsにはありませんが、あったらいいのにと思います。
7. セマンティックフォーム
私はセマンティック HTML に夢中です。Rails のフォーム ビルダーは非常に醜い HTML を生成するため、多くの人がFormtasticを使用しました。これは、より意味のあるフォームを生成します。Tower.js は Formtastic とほぼ同じ API を使用します。また、セマンティック テーブル ビルダーも備えているため、管理ビュー用の検索可能/並べ替え可能なテーブルを簡単に作成できます。
8. 資産パイプライン
Rails 3 には素晴らしいアセット パイプラインがあり、JavaScript を CoffeeScript で記述し、CSS を SCSS で記述すると、自動的に再コンパイルされます。次にrake assets:precompile
、アセットと md5 でハッシュされた gzip されたアセットを S3 で使用できるようにします。これを自分で構築するのは非常に困難であり、Node.js でこれに取り組んでいる人を見たことがありません。
RailwayJS は Rails 2 メソッドを使用してアセット パスにタイムスタンプを付けるため、この md5 ハッシュ バージョンの代わりに:
/stylesheets/application-51e687ad72175b5629f3b1538b65ea2c.css
次のような結果が得られます。
/stylesheets/application.css?1306993455524
これは、いくつかの重要な理由から問題になります。Rails Asset Pipeline Guideに詳細がありますが、大きな問題は S3 がタイムスタンプを認識しないため、/stylesheets/application.css を読み取っていることです。また、遠い将来のExpires
ヘッダーを設定して CSS を変更した場合は、以前にあなたのサイトにアクセスしたユーザーは、キャッシュを削除するか、ページを強制的に更新して更新を確認する必要があります。
RailwayJS には、組み込みのアセット コンパイル パイプラインもありません (少なくとも私の知る限り)。
9. ウォッチファイル
Guardは、Rails の生産性を大幅に向上させました。パターンに一致するファイルが作成/更新/削除されたときに実行される、基本的には rake/cake タスクのような、迅速な「監視タスク」を作成できました。
Tower にはこれが組み込まれています ( design.ioを使用)。これは実際には、CoffeeScript および Stylus アセットを JavaScript および CSS にコンパイルするように指示しているものです。しかし、この機能で非常に強力なことを行うことができます。例については、 https://github.com/guard/guard/wiki/List-of-available-Guardsを参照してください。
10. コーヒースクリプト
CoffeeScriptの大ファン。
CoffeeScript を使用すると、記述する必要のある JavaScript の量が約半分に削減されます ( 6,501 個の追加、15,896 個の削除により、Node.js ライブラリ全体が CoffeeScript に変換されます)。また、コーディングがはるかに高速かつ簡単になります。
また、CoffeeScript は、Rails が世界に示した生産的で楽しいコーディング体験を維持する唯一の方法です。JavaScript はそれをしません。
ささいなこと
私は標準のファンです。RailwayJS は、snake_case を使用するという Ruby の規則に固執していました。私もそれをやりたかったのですが、JavaScript コミュニティーは camelCase を使用しているため、Tower はそれを採用しました。CamelCase にはいくつかの追加の利点もあります。たとえば、サーバー側の Rails snake_case をクライアントの camelCase との間で変換する必要がなく、その余分な文字を削除するとファイル サイズがわずかに小さくなります。
また、非常にクリーンなコードも気に入っています。プロジェクトへの貢献を検討する前に、ソース コードを一通り読みます...そして、非常に面倒な場合は、おそらく書き直すだけです。
コードの最適化も大好きです。Tower.js の大きな目標は、可能な限り最小限のコードを使用してクライアントとサーバーの両方でまったく同じ API を提供し、Rails が行うすべてのことを行うように構造化することです。ただし、コードベースのサイズを最小限に抑えることと、明確で楽しく生産的なコードを作成することの間にはトレードオフがあります。両方の世界を最大限に活用する方法をまだ見つけています。
私も間違いなくこれに長期的に参加しています。これが私たちの会社の基盤であり、私が個人的に将来構築するすべてのものです。うまく設計され、機能的で、高度に最適化されたアプリを 1 日で送り出せるところまで到達したいと考えています。
それが役立つことを願っています。