65 votes

RailwayJS et TowerJS

Encore une fois... en sélectionnant le cadre. Je me suis arrêté sur ces deux TowerJS et RailwayJS, mais il semble qu'ils soient très similaires et il est très difficile de choisir.

Les deux sont basés sur Express, les deux sont des frameworks de style RoR...

Lequel est le plus prometteur, lequel sera le plus populaire ?

Ou peut-être suis-je déjà sur la mauvaise voie ? Je devrais peut-être choisir un autre cadre.

Je déteste qu'il y ait tant de frameworks parmi lesquels choisir, qu'il n'y ait pas de norme industrielle sur laquelle s'appuyer pour être plus ou moins sûr que le framework sera développé dans quelques années...

Aidez-moi, j'ai besoin de l'avis d'un expert. Merci

153voto

Lance Pollard Points 17503

Voici un bref tableau d'ensemble, je parlerai de certains éléments plus loin.

+-----------------------+------------------------------+------------------------------------+
|                       | RailwayJS                    | Tower.js                           |
+-----------------------+------------------------------+------------------------------------+
| First commit          | Jan 2011                     | Oct 2011                           |
| Rails                 | 2.3.x                        | 3.x                                |
| Node.js               | >= 0.4.x                     | >= 0.4.x                           |
| Server                | ✓                            | ✓                                  |
| Client                |                              | ✓                                  |
| Template agnostic     | ✓                            | ✓                                  |
| Default engine        | EJS                          | CoffeeKup                          |
| Database agnostic     | ✓                            | ✓                                  |
| Default datastore     | MongoDB                      | MongoDB                            |
| Model validations     | validatesPresenceOf('email') | validates('email', presence: true) |
| Query scopes          | ✓                            | ✓                                  |
| Chainable scopes      |                              | ✓                                  |
| Param parsing         |                              | ✓                                  |
| Controllers           | ✓                            | ✓                                  |
| Resource controllers  |                              | ✓                                  |
| File naming           | users\_controller.js          | usersController.coffee             |
| vm.runInCustomContext | ✓                            |                                    |
| Asset pipeline        |                              | ✓                                  |
| Asset compression     |                              | ✓                                  |
| Routing               | map.resources('posts')       | @resources 'posts'                 |
| Nested routes         | ✓                            | ✓                                  |
| Generated url helpers | ✓                            |                                    |
| Generators            | ✓                            | ✓                                  |
| Command-line api      | ✓                            | ✓                                  |
| REPL (console)        | ✓                            | ✓                                  |
| CoffeeScript console  |                              | ✓                                  |
| Asset cache method    | timestamp                    | md5 hash                           |
| Production asset path | /app.css?123123123           | /app-859c828c89288hc8918741.css    |
| Preferred Language    | JavaScript                   | CoffeeScript                       |
| CoffeeScript support  | ✓                            | ✓                                  |
| Internationalization  | ✓                            | ✓                                  |
| Heroku support        | ✓                            | ✓                                  |
| String case           | snake\_case                   | camelCase                          |
| Form builder          | ✓                            | ✓                                  |
| Semantic form builder |                              | ✓                                  |
| Table builer          |                              | ✓                                  |
| File watcher API      |                              | ✓                                  |
| Live-reload assets    |                              | ✓                                  |
| Test suite            |                              | ✓                                  |
| Generators for tests  |                              | ✓                                  |
| Twitter Bootstrap     | ✓                            | ✓                                  |
| HTML5 Boilerplate     |                              | ✓                                  |
+-----------------------+------------------------------+------------------------------------+

J'ai créé Tower.js pour atteindre plusieurs objectifs qu'aucun des frameworks existants ne permettait de réaliser de manière adéquate. Voici quelques-uns de ces objectifs.

1. Même code sur le client et le serveur

Depuis que Node.js a rendu JavaScript possible sur le serveur, il n'y a aucune raison d'écrire une partie de l'application en Rails, et l'autre en Backbone. C'est tout sauf DRY. Vous devriez pouvoir définir les modèles une fois et les utiliser à la fois sur le client et le serveur.

RailwayJS ne fonctionne que sur le serveur car il a été construit autour d'express. Tower.js est également construit autour d'express mais d'une manière qui le fait fonctionner à la fois pour le client et le serveur. Tower.js fournit exactement la même API pour le client et le serveur. Cela signifie que j'ai dû réécrire certaines choses, comme le routeur, pour qu'il fonctionne de la même manière sur le client et sur le serveur (en plus, il vous permet de faire des choses comme history.pushState avec le # de secours, en utilisant le même ensemble de routes).

2. Mêmes "vues" sur le client et le serveur

J'ai passé beaucoup de temps dans Rails et à écrire des templates Haml. Parallèlement, j'écrivais des interfaces JavaScript pour le web et les mobiles en utilisant des langages de template comme Mustache. Il s'agit d'une duplication de code supplémentaire Vous devriez être en mesure d'utiliser le même ensemble de vues/templates à la fois sur le client (en tant que templates JavaScript) et sur le serveur (en rendant du HTML statique).

Comme Haml était assez génial (super propre, permettait d'exécuter des rubis arbitraires, intégrait la fonction de pretty-printing, etc.), l'alternative JavaScript la plus proche était CoffeeKup . Et il fonctionne aussi bien sur le client que sur le serveur. CoffeeKup vous permet d'écrire des modèles avec toute la puissance de JavaScript, vous n'avez donc aucune limite. Construire un FormBuilder dans Mustache va demander beaucoup de travail ou beaucoup de code, ou les deux.

Notez cependant que vous êtes libre de changer de moteur de template et d'utiliser Jade, Mustache, Handlebars, etc. pour le client ou le serveur. CoffeeKup est simplement une solution par défaut propre et puissante.

3. API de modèle de qualité Rail sur le client et le serveur

ActiveModel (implémenté par ActiveRecord pour SQL et Mongoid pour MongoDB pour Rails) est une API très complète et bien testée permettant aux développeurs de définir et d'interagir avec les données. Elle est à la fois puissante et agréable. Toutes les implémentations JavaScript précédentes (et actuelles) n'ont jamais été aussi robustes et bien conçues, et je ne vois rien de tel dans un avenir proche.

Si tu peux écrire ça en Rails :

User.where(:email => /[a-z/).page(2).limit(20)

Vous devriez être en mesure de le faire en JavaScript :

App.User.where(email: /[a-z/).page(2).limit(20)

Tower.js est livré avec des "scopes chaînables", c'est-à-dire des requêtes en dur + une pagination. Il est calqué sur le modèle API de requête MongoDB mais cette "entrée" API est convertie en commandes de base de données appropriées pour les différents magasins de données.

4. Interface uniforme avec les datastores SQL et NoSQL

Tower.js dispose actuellement d'un magasin MongoDB et Memory (dans le navigateur), et vise à fournir une interface uniforme pour le reste des bases de données populaires (CouchDB, Neo4j, PostGreSQL, MySQL, SQLite, Cassandra, etc.)

RailwayJS semble faire de même via JugglingDB, et cela semble être un bon début. Mais j'ai choisi de ne pas l'utiliser pour plusieurs raisons. Premièrement, il semble qu'il soit construit autour de l'API Rails 2.x ( User.validatesUniquenessOf "email" vs. User.validates "email", presence: true ). Deuxièmement, il n'a pas la richesse des requêtes chaînables que possède Rails 3. Troisièmement, je veux pouvoir ajouter du code à la base de code rapidement, et comme je suis très pointilleux, je finirais probablement par remanier l'ensemble pour utiliser CoffeeScript, haha. Et je ne veux pas construire une couche autour de ça parce que ça doit fonctionner sur le client aussi, donc garder l'architecture de la bibliothèque aussi minimale que possible est une priorité élevée.

5. Contrôleurs débrouillards

El ressources héritées Ruby gem a supprimé environ 90 % du code de mes contrôleurs Rails. Elle a trouvé un ensemble de conventions pour implémenter les 7 actions de base du contrôleur. Tower.js inclut quelque chose comme ça, donc par défaut vous n'avez pas à écrire de code dans vos contrôleurs, ils répondront toujours avec JSON et HTML. Il permet également de définir des routes imbriquées.

6. Analyseur automatique de requêtes entre URL et base de données

Dans Tower.js, vous pouvez indiquer à un contrôleur de surveiller des paramètres spécifiques dans l'url et il les convertira en un hachage prêt à être appliqué à une requête de modèle.

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}

Étant donné une url qui ressemble à /users?email=abc&something=random alors @criteria() vous donnera un hash {email: /abc/} .

Ce n'est pas dans Rails, mais j'aimerais que ce soit le cas.

7. Formes sémantiques

Je suis à fond dans le HTML sémantique. Le constructeur de formulaires de Rails génère un HTML plutôt laid, si bien que de nombreuses personnes, ainsi que moi-même, ont utilisé Formtastic qui génère des formes plus sémantiques. Tower.js utilise à peu près la même API que Formtastic. Il dispose également d'un générateur de tableaux sémantiques, qui permet de créer facilement des tableaux interrogeables/triables pour les vues d'administration.

8. Pipeline d'actifs

Rails 3 disposait d'un formidable pipeline d'actifs, dans lequel vous pouviez écrire votre JavaScript en CoffeeScript, votre CSS en SCSS, et il se recompilait automatiquement. Puis rake assets:precompile vos ressources et vous obtiendrez des ressources gzippées et hachées en md5, prêtes pour S3. C'est assez difficile à construire soi-même, et je n'ai vu personne travailler sur ce sujet pour Node.js.

RailwayJS utilise la méthode Rails 2 d'horodatage du chemin d'accès au bien, donc au lieu de cette version md5-hashed :

/stylesheets/application-51e687ad72175b5629f3b1538b65ea2c.css

Tu obtiendrais quelque chose comme ça :

/stylesheets/application.css?1306993455524

C'est un problème pour quelques raisons importantes. Le site Guide Rails Asset Pipeline a les détails, mais la grande chose est que S3 ne reconnaît pas l'horodatage, donc il lit /stylesheets/application.css, et si vous définissez un futur lointain Expires et que vous avez modifié votre CSS, toute personne ayant visité votre site auparavant devra purger son cache ou rafraîchir votre page pour voir les mises à jour.

RailwayJS ne dispose pas non plus du pipeline de compilation des actifs intégré (du moins à ma connaissance).

9. Le fichier de veille

Garde a été un énorme accélérateur de productivité dans Rails. Il vous permettait d'écrire des "tâches de surveillance" rapides, essentiellement comme des tâches rake/cake, qui s'exécutaient lorsqu'un fichier correspondant à un modèle était créé/mise à jour/supprimé.

Tower intègre cette fonction (en utilisant design.io ). C'est en fait ce qui indique aux ressources CoffeeScript et Stylus de compiler en JavaScript et CSS. Mais vous pouvez faire des choses très puissantes avec cette fonctionnalité, voir https://github.com/guard/guard/wiki/List-of-available-Guards par exemple.

10. CoffeeScript

Grand fan de CoffeeScript.

CoffeeScript réduit de moitié la quantité de JavaScript que vous devez écrire ( 6 501 ajouts, 15 896 suppressions en convertissant toute la bibliothèque Node.js en CoffeeScript). Et cela rend le codage beaucoup plus rapide et facile.

En outre, CoffeeScript est le seul moyen de conserver cette expérience de codage productive et agréable que Rails a fait découvrir au monde. JavaScript ne fait pas ça.

Les petites choses

Je suis un fan des standards. RailwayJS s'en tenait à la convention Ruby d'utiliser snake_case, et je voulais faire de même, mais la communauté JavaScript utilise camelCase, et Tower s'en est donc tenue à cela. CamelCase présente également quelques avantages supplémentaires, comme le fait qu'il n'est pas nécessaire de convertir le snake_case de Rails côté serveur en camelCase pour le client, et que la suppression de ce caractère supplémentaire permet de réduire la taille du fichier.

Je suis également amoureux du code super propre. Avant d'envisager de contribuer à un projet, je lis le code source... et s'il est super désordonné, je vais probablement le réécrire.

J'aime aussi optimiser le code. Avec Tower.js, l'un des principaux objectifs est de le structurer de manière à ce qu'il fasse tout ce que fait Rails, en fournissant exactement la même API au client et au serveur, en utilisant le moins de code possible. Il y a cependant un compromis à faire entre la réduction de la taille du code et l'écriture d'un code clair et agréable à utiliser. Je cherche encore des moyens d'obtenir le meilleur des deux mondes.

Je suis définitivement là pour le long terme aussi. C'est la base de notre entreprise, et de tout ce que je construirai personnellement à l'avenir. Je veux arriver au point où vous pouvez produire une application bien conçue, fonctionnelle et hautement optimisée en un jour.

J'espère que cela vous aidera.

5voto

Juzer Ali Points 1589

Avez-vous fait attention à Derbyjs ? Celui-ci, bien qu'il ne soit pas encore en version bêta, est assez excitant. Il est réalisé par un ancien employé de Google et l'auteur de everyauth . Vous devrez écrire un minimum de javascript côté client avec celui-ci. Voir les extraits tirés de la page officielle :

Pourquoi ne pas utiliser Rails et Backbone ? Derby représente une nouvelle race de d'applications, qui, selon nous, remplaceront les bibliothèques bibliothèques populaires comme Rails et Backbone.

L'ajout de fonctionnalités dynamiques aux applications écrites avec Rails, Django et d'autres frameworks côté serveur tend à produire un fouillis. Le code du serveur rend divers états initiaux tandis que les sélecteurs et les callbacks de jQuery tentent désespérément de donner un sens au DOM et aux événements de l'utilisateur. L'ajout de de nouvelles fonctionnalités implique généralement de modifier le code du serveur et du client, souvent dans des langages différents.

De nombreux développeurs incluent désormais un framework MVC client comme Backbone pour mieux structurer le code client. Quelques-uns ont commencé à utiliser la liaison déclarative bibliothèques de liaison modèle-vue déclaratives, comme Knockout et Angular, pour réduire la les manipulations DOM et les liaisons d'événements passe-partout. Il s'agit là d'excellents concepts, et l'ajout d'une certaine structure améliore certainement le code client. Cependant, ils conduisent toujours à la duplication du code de rendu et à la synchroniser manuellement les changements dans des bases de code serveur et client de plus en plus complexes. bases. De plus, chacune de ces pièces doit être manuellement câblée ensemble et emballé pour le client.

Derby simplifie radicalement ce processus d'ajout d'interactions dynamiques. dynamiques. Il exécute le même code dans les serveurs et les navigateurs, et il synchronise les données automatiquement. Derby s'occupe du rendu des modèles, de l'empaquetage, et des liaisons modèle-vue. Puisque toutes les fonctionnalités fonctionnalités sont conçues pour fonctionner ensemble, aucune duplication de code et aucun nécessaire. Derby équipe les développeurs pour un futur où toutes les données dans toutes les applications seront en temps réel.

Flexibilité sans le code de collage Derby élimine la fastidieuse tâche consistant à câblage d'un serveur, d'un moteur de mise en page de serveur, d'un compilateur CSS, script packager, minifier, framework MVC client, bibliothèque JavaScript client, moteur de templating et/ou de bindings client, histogramme client. client, moteur de templating et/ou de bindings client, bibliothèque d'historique client, transport en temps réel, ORM, etc. bibliothèque d'historique client, transport en temps réel, ORM et base de données. Il élimine la complexité du maintien de la synchronisation de l'état entre les modèles et les vues, les clients et les serveurs, les fenêtres multiples, les utilisateurs multiples, les modèles et les bases de données. bases de données.

En même temps, il joue bien avec les autres. Derby est construit sur le dessus de bibliothèques populaires, dont Node.js, Express, Socket.IO, Browserify, Stylus, UglifyJS, MongoDB et bientôt d'autres bases de données et applications populaires. banques de données. Ces bibliothèques peuvent également être utilisées directement. Les données de synchronisation des données, Racer, peut être utilisée séparément. D'autres bibliothèques clients, comme jQuery, et d'autres modules Node.js de npm fonctionnent. fonctionnent tout aussi bien avec Derby.

Lorsque vous suivez la structure de fichiers par défaut, les modèles, les styles et les scripts sont automatiquement emballés. sont automatiquement emballés et inclus dans les pages appropriées. appropriées. En outre, Derby peut être utilisé par le biais d'une API dynamique, comme on peut le voir dans le fichier l'exemple simple ci-dessus.

Mais il est également accompagné de l'avertissement suivant

Derby et Racer sont des logiciels alpha. Alors que Derby devrait bien fonctionner suffisamment bien pour le prototypage et les projets du week-end, il est toujours en cours de développement majeur. Les API sont susceptibles d'être modifiées.

Il n'y a pas encore d'implémentation d'autorisation et il y a beaucoup de problèmes. questions de sécurité mais ils seront pris en charge dans les mois à venir. Si vous pouvez attendre quelques mois, ce cadre semble être prometteur.

3voto

Shane Courtrille Points 5150

Le choix d'un cadre dépend de votre niveau de confort avec celui-ci généralement basé sur

  • Quel est le degré d'activité du projet ? Quand a eu lieu le dernier commit ? S'il n'est pas sur Github, c'est une préoccupation immédiate pour moi car cela rend les contributions des utilisateurs plus difficiles.

  • Combien d'articles de blog puis-je trouver sur le cadre ? Si personne n'en parle, c'est généralement mauvais signe, car les gens parlent naturellement des choses qui les passionnent.

  • Qu'est-ce que I pensez-vous du cadre ? Cela peut être plus difficile à juger, mais il devrait y avoir suffisamment d'exemples pour que vous puissiez vous faire une idée de base au moins. S'il n'y en a pas, c'est un gros problème en soi.

Erm bien sûr, la question évidente est la suivante : si vous voulez un framework RoR pourquoi ne pas simplement utiliser RoR ? ;)

3voto

Il semble que TowerJS soit plus étroitement couplé avec MongoDB comme magasin de données, alors que RailwayJS semble avoir une flexibilité d'adaptateur de modèle. Cela pourrait influencer votre choix entre les deux. Personnellement, je choisirais d'écrire des sites Rails en utilisant RoR. Node semble se prêter davantage à différents types de services, ne pensez-vous pas ? (Je pense à Backbone dans le client avec des services AJAX REST).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X