Riot 1.0

IMPORTANT Cette version n’est plus maintenue

Introduction à Riot 1.0

Riot est l’approche la plus minimale possible au monde du MVC. La bibliothèque pèse 1ko et a seulement 3 méthodes publiques, ce qui le rend extrêmement simple à apprendre. Une application Riot utilise du JavaScript vanilla pour structurer le code. Vous utiliserez des schémas de conception classiques au lieu d’idiomes spécifiques à certains frameworks.

Les applications Riot sont modulaires et peuvent être maintenues par de multiples développeurs. Sa nature anti-framework vous force à vous concentrer sur le plus important: votre logique métier et l’API.

Pour une introduction plus approfondie, consultez le post d’origine sur le blog.

Qu’est-ce qui est modulaire ?

Votre rôle est de construire des applications pouvant être décomposées en modules. Chaque module s’occupe d’une certaine fonction logique et n’est pas dépendant des autres modules. Cela apporte de gros avantages:

  1. Un gros programme peut être cassé en plus petites et plus simples unités
  2. Les modules peuvent être ajoutés/retirés/modifiés sans affecter les autres parties de l’application
  3. Plusieurs programmeurs peuvent travailler sur des modules individuels en même temps
  4. La structure du programme est simple à comprendre même pour les nouveaux venus
  5. La capacité à construire un sous-ensemble de modules pour des besoins différents

La modularité est l’élément clé pour les applications de grande échelle. Fondamentalement, une application modulaire consiste en deux choses:

  1. un noyau (Core)
  2. des modules

Le noyau de l’application est un bout de logiciel avec une API bien documentée. Il ne s’agit pas juste d’une couche données, comme vous pouvez le voir sur certaines installations MVC – il s’agit de la précieuse logique métier.

Les modules sont les extensions à ce noyau. Ces modules sont “faiblement couplés”, ce qui signifie qu’ils viennent se greffer au noyau en observant les événements émis par celui-ci. Ainsi, le noyau n’a pas connaissance de ces modules.

Il n’y a pas de références à des fonctions écrites en dur car le couplage fort fonctionne mal à plus grande échelle. Il peut y avoir des dépendances déclarées en dur dans le noyau, mais pas entre le noyau et les modules.

Garder les choses modulaires implique en fait une constante organisation du travail. Chaque chose doit être à sa place la plus logique. Faites l’analogie avec les calques dans Photoshop, la table des matières dans un livre ou la hiérarchie visuelle dans une interface utilisateur. C’est une recherche permanente d’équilibre. Et quand vous ajoutez des fonctionnalités, elles doivent trouver leur place dans le cadre.

Modèle, Vue, et Présentation

Quand on parle de modularité dans des applications mono-page, mieux vaut mettre les choses à plat.

Avant tout, vous devez connaître les objectifs de votre application. Qu’est-ce que ça fait et qu’est-ce que ça ne fait pas ? Vous modélisez votre logique métier en JavaScript: c’est votre noyau applicatif. Aussi appelé Modèle.

Ensuite, vous avez le navigateur et l’interface utilisateur. Le HTML, le document (DOM) et le style (CSS). La partie que l’utilisateur voit et interagit avec. C’est la Vue.

Puis vous devez relier ces deux choses ensemble. Vous devez réagir aux événements survenant sur la Vue: clics, touches pressées, défilements… Vous devez aussi observer les changements du Modèle: peut-être qu’une nouvelle entrée est venue d’un canal temps réel, ou que quelqu’un a commenté un article. Ce composant doit observer tous ces événements et y réagir en conséquence.

Cet “entremetteur” constitue la couche dite de Présentation.

Riot utilise ces termes pour décrire Riot dans son ensemble: Modèle, Vue et Présentation (MVP).

Le MVP a comme objectif essentiel de séparer la logique applicative (Modèle) de l’interface utilisateur (Vue). Cette séparation est importante car elle simplifie votre code et le rend plus facilement testable. Ce manque de séparation à haut niveau cause ce qu’on appelle le “code spaghetti” où le métier et l’interface utilisateur sont mélangés entre eux. C’est l’ère jQuery avant que les applications mono-page aient commencé à gagner en popularité.

Dans la terminologie classique UI, Riot utilise la branche Vue passive (1) de la famille MVP.

L’approche Vue Passive réduit la logique comportementale des composants d’interface à son minimum en utilisant un contrôleur qui en plus de réagir aux événements utilisateur, se charge également de mettre à jour toute la vue.

Contrairement à la plupart des configurations MVC, la Vue Passive permet de n’avoir aucune dépendance entre la Vue et le Modèle. C’est un modèle de conception simple à comprendre et à implémenter – ce qui vous rend finalement plus performant.

Enfin, il est important de réaliser que MVP (ou MVC) n’est pas un framework. C’est un schéma de conception à haut niveau. Son but est de simplifier l’achitecture des applications aux interfaces chargées. C’est un moyen simple de structurer vitre code. Dans des applications à couplage faible, les modules communiquement les uns avec les autres avec des événements.

La plupart des frameworks actuels sont superflus car fondamentalement, tout ce dont vous avez besoin est un bon système d’événements.

Modèle

Le Modèle est le noyau de l’application. C’est la partie la plus importante de votre application, car tout est construit par-dessus. C’est l’interface publique au reste du monde. Vous l’utiliserez, votre équipe l’utilisera, et des personnes tierces l’utiliseront.

Un noyau d’application bien conçu peut être étendu avec des modules à couplage faible et permet à chacun de développer soi-même le système.

Dans Riot, le modèle est une application complète et non juste un objet utilitaire pour la couche Présentation comme vous avez pu le voir sur des configurations MVC. C’est aussi une bonne pratique d’avoir des modèles assez gros comparés aux vues car au plus vous vous rapprochez de la vue, plus il devient difficile de tester le code. Tout ce qui est difficile à tester devrait avoir un comportement minimal.

Cela permet de développer de multiples interfaces utilisateur par-dessus le même Modèle. Prenez l’exemple de Twitter et de ses différents clients (du temps où tout allait bien avec eux). Les gens pourraient développer des expériences très différentes par-dessus la même API sans même se connaître.

Concevoir le Modèle

Le Modèle est le point de départ de la conception d’une application (la Vue en est un autre, selon les préférences). Vous devriez vous réserver du temps pour concevoir le Modèle et le rendre le plus simple possible car vous passerez beaucoup de temps à l’utiliser ensuite. Mettez la barre très haut. Pensez à l’API jQuery par exemple.

Deux choses à garder en tête:

  1. Quel problème résout le produit ?
  2. Qui utilise le produit ?

Le Modèle est un domaine bien spécifique. Pensez à ce que votre application fait, quels sont les objectifs, quelles fonctionnalités sont présentes et lesquelles ne le sont pas. Décomposez votre business en pièces logoqies et réfléchissez à comment elles communiquent. Ce que vous avez déjà dû faire par le passé avec les langages orientés objet.

Gardez tout cela en mémoire lorsque vous concevez les propriétés, méthodes, événements. Sans aller plus loin, disons que l’API est la racine du bien et du mal.

Backend (Serveur)

Riot n’inclut aucun composant serveur séparé. C’est un choix de conception. REST domine actuellement la façon de penser, mais les Web Sockets et les patterns temps réel sont juste au coin de la rue, et les protocoles de style RPC auront alors plus de sens.

Votre interface serveur peut juste avoir une méthode générique call afin que toute l’implémentation sous-jacente puisse changer. Peu importe qu’il s’agisse de REST, RPC ou d’un truc personnalisé en AJAX.

Vue

La Vue est ce que l’utilisateur voit et interagit avec. C’est la page HTML sur un navigateur. Ce qui est en fait intéressant pour un développeur JavaScript est le modèle document (DOM). Vous pouvez utiliser toutes sortes d’astuces créatives pour concevoir des expériences utilisateur. Il s’agit surtout d’une source d’événements:

  1. Evénements utilisateur: clics, défilements, touches pressées, souris déplacée etc…
  2. Evénement “ready” du document
  3. Changement d’URL

Ces événements présentent un intérêt pour la couche Présentation, qui s’occupe de la manipulation concrète de la vue. La vue en elle-même n’a pas de logique - juste du bon vieux code HTML et CSS.

Presentation

La couche Présentation et l’important médiateur entre la Vue et le Modèle. Chaque Présentateur est un module faiblement couplé effectuant une fonction bien particulière et pouvant être développé individuellement du reste.

Le Présentateur écoute les événements de la Vue et appelle les méthodes appropriées côté API. Il écoute également les événements des Modèles et manipule le DOM en conséquence.

La couche Présentation ne fait aucune afirmation sur le modèle business.

Notez que d’autres frameworks peuvent appeler cette couche la “Vue”, mais dans le modèle MVP on l’appelle bien Présentation.

Templates

Parfois j’aime commencer développer une application mono-page avec juste du HTML et du CSS. C’est incroyable tout ce que vous pouvez faire avec juste ça. Vous pouvez peaufiner le design et l’interface utilisateur presque totalement. En ajoutant de simples noms de classes CSS en JavaScript, vous pouvez faire ces belles transitions de vues. En réalité, bien sûr vous ferez du JavaScript mais il est tout à fait possible de montrer au client l’interface complète d’une application sans une seule ligne de code logique.

Le mieux dans tout ça est que vous pouvez naturellement compléter cette vue HTML pour faire l’application entière. Idéalement, vous avez également complété l’API et il ne vous reste plus qu’à coder la couche Présentation pour les relier ensemble.

Ce déguisement HTML est une collection de templates. Avant de commencer avec la Présentation, vous pouvez déplacer certaines parties de ce HTML à l’intérieur de balises <template/> ou <script type='text/template'/> , typiquement celles qui seront amenées à être reproduites plusieurs fois à l’intérieur de boucles.

Pas de logique

Riot a une position forte qui est déconseiller de mettre de la logique à l’intérieur des templates. Il y a plusieurs raisons à cela:

  1. Du HMTL pur est plus propre et passe le validateur W3C. Un HTML mélangé avec une syntaxe de templating est désordonné.

  2. HTML n’a pas été conçu à la base pour décrire de la logique

  3. Les boucles dans les templates ne sont pas nécessaires dans les applications temps réel où les listes itérables peuvent changer avec le temps. Il s’agit probablement du défi le plus important des langages de templates actuels.

  4. La logique à l’intérieur du HTML est difficile voire impossible à tester

  5. Les templates sans logique sont parfois plus rapides d’un ordre de grandeur, surtout sur les navigateurs sans Webkit (2)

  6. Dans les boucles complexes, il est naturel de laisser la logique de calcul des données à JavaScript et de garder les templates propres.

Regardez la logique de ce listing client. L’unique template est interprété plusieurs fois à l’intérieur d’une boucle et la propriété width est calculée en JavaScript pour garder le template simple.

Routage

L’application de démonstration gère le routage en couche présentation comme ceci:

// 1. Liens
app.root.on("click", "[href^='#/']", function(e) {
  riot.route($(this).attr("href"))
})


// 2. Routage (association entre les URL et les méthodes API)
riot.route(function(path) {
  app.load(path.slice(2))
})


// 3. Logique d'interface
app.on("before:load", function() {

  // supprime la classe existante
  $(".page.is-active").removeClass("is-active")

}).on("load", function(view) {

  // en met une autre
  $("#" + view.type + "-page").addClass("is-active")

})

Voilà comment cela fonctionne:

  1. Liens: sélectionne les liens s’occupant de la bascule entre les vues et change l’URL. Nous utilisons les événements délégués jQuery pour récupérer à la demande tous les liens ancre de la page, même s’ils sont créés dynamiquement plus tard.

  2. Routage: Définit la méthode API à appeler quand l’URL change. Cette application de démonstration a une suele méthode générique load prenant un nom de page en argument, mais vous pouvez avoir une association plus complexe entre les URL et les méthodes.

  3. Logique d’interface: Définit ce qui se passe dans l’interface quand une méthode API est appelée et que des données (ou une “page”) est retournée par le serveur. Ici nous assignons une classe CSS “is-active” pour animer la page en utilisant des transitions CSS.

L’API émét des événements “before:load” et “load” afin que la couche présentation puisse implémenter la logique de bascule de page via les gestionnaires d’événements. De cette façon, vous pouvez appeler la méthode load de l’API depuis la console aussi, et l’UI se comportera de la même manière qu’en cliquant sur les liens de navigation.

Le routage est l’une des choses principales qui définissent un framework côté client. Dans Riot, la fonction riot.route est une couche mince par-dessus l’API pour gérer le bouton Précédent. L’API peut se concentrer sur la logique métier sans se soucier de la couche web. Le routage côté présentation est complètement transparent et chacune des étapes peut être personnalisée selon les besoins de votre application.

Le code ci-dessus s’occupe uniquement de la bascule et le rendu de la page retournée est géré par un présentateur différent, spécifique à cette vue.

jQuery

jQuery existe car les API natives pour manipuler le DOM sont désastreuses pour travailler. jQuery fait un nettoyage massif en exposant le DOM au développeur d’une manière élégante et amicale.

Il y a d’autres implémentations (3), mais tout le crédit revient à John Resig. Il a conçu l’API, qui est devenue un standard.

Soyez libres d’utiliser une autre implémentation, mais les avantages de jQuery en lui-même sont:

jQuery est actuellement présent sur 58% de tous les sites web et 93.0% de tous les sites web utilisant une bibliothèque JavaScript connue (4). Ces nombres sont en croissance permanente.

L’API jQuery est une correspondance parfaite pour Riot. C’est l’outil ultime pour coder la couche Présentation. Les sélecteurs jQuery fournissent une manière non obstrusive de relier le modèle à la vue. Et il peut y avoir de multiples présnetateurs gérant le même ensemble d’éléments HTML sans avoir connaissance les uns des autres.

Les ID et les noms de classes fournissent des mécanismes naturels pour y associer des fonctionnalités, tout comme vous leur associez des styles en CSS. Souvenez-vous juste que si les ID et noms de classes changent, vous devrez également modifier le code des présentateurs.

Notez que riot n’est pas dépendant de jQuery. Vous pouvez utiliser d’autres bibliothèques DOM telles que DOJO ou MooTools ou vous pouvez utiliser React de Facebook.

Interface de Module

Concentrons-nous maintenant sur le codage. Nous voulons un moyen simple d’étendre le noyau de l’application avec des modules. Voici une astuce avec riot.observable pour diviser l’application en modules faiblement couplés:

// le fait fonctionner en client comme en serveur
var global = is_node ? exports : window,
  instance

// une seule variable globale exposée
global.admin = riot.observable(function(arg) {

  // si appelé sans arguments, l'API est retournée
  if (!arg) return instance

  // argument fonction --> lie un nouveau module
  if ($.isFunction(arg)) {
    admin.on("ready", arg)

  // argument de configuration --> démarre l'application
  } else {
    instance = new Admin(arg)

    instance.on("ready", function() {
      admin.trigger("ready", instance)
    })

  }

})

Le code ci-dessus expose une unique variable globale admin qui peut être utilisée comme ceci:

admin(function(api) {
  // logique du module #1 , l'API est donnée en argument
})

admin(function(api) {
  // logique du module #2
})

Toutes les fonctionnalités d’interface sur l’application de démonstration est encapsulée à l’intérieur de modules comme ceux-ci. Une fois que vous avez tout le code à l’intérieur de modules, vous devez lancer l’application:

admin({ page: location.hash.slice(2), root: $("body") })

Cela démarrera l’application avec la configuration donnée en argument et tous les modules sont initialisés quand l’événement “ready” est déclenché. Cet événement est typiquement appelé après que le DOM est chargé en fin de page ou alors à l’intérieur d’un appel à la fonction jQuery $(document).ready. L’argument donné contient typiquement le chemin initial de l’application, ainsi que l’élément racine. Votre application a son propre enssemble de variables de configuration, bien sûr.

Vous pouvez accéder à l’API une fois l’initialisation faite comme ceci:

var api = admin() // obtenir l'API

api.load("customers") // appelle une méthode de l'API, essayez aussi avec "stats" par exemple

Essayez ça en console JavaScript sur la démo (vous devez être connectés) ! Totues les fonctionnalités que vous pouvez faire utiliser via l’interface sont également disponibles sur l’API. Ceci est assuré par la séparation stricte entre l’API et les modules de la couche Présentation.

A présent, votre application est bien divisée en modules découplés et vous avez une méthode simple pour rajouter de nouveaux modules. Chacun des membres de votre équipe a une seule méthode globale admin à utiliser et l4API est donne en premier argument de chaque module. Les modules sont isolés et peuvent être librement ajoutés / retirés sans casser les autres parties de l’application. Vous pouvez avoir des modules à la fois en couche API et en couche Présentation.

Au final, l’interface de module est en “marque blanche”. Vous pouvez nommer les modules cruciaux selon votre application et il n’y a pas de framework tiers pour forcer les noms à utiliser. Bien plus sympa!

Cycle de vie de l’application

Quand l’application démarre, une séquence d’événements survient. Voici le cheminement classique:

  1. Un appel au serveur est fait pour charger les données initiales de la vue
  2. L’API est entièrement construite
  3. Les modules sont initialisés
  4. Un événement “load” est déclenché et retourne les données initiales

Une application nécessitant une authentification nécessite une étape supplémentaire pour gérer les cas d’échecs d’authentification.

Maitenant regardons le code:

// 1. charge les données initiales depuis le serveur
backend.call("init", conf.page).always(function(data) {

  // 2. construit l'API, nous construisons seulement un objet User dans cette démo
  self.user = new User(self, data ? data.user : {}, backend)

  // 3. tout est prêt --> les modules sont chargés
  self.trigger("ready")

// l'initialisation a été un succès
}).done(function(data) {

  // 4. événement load
  self.trigger("load", data.view)

// l'initialisation a échoué
}).fail(function() {

  // attend que l'utilisateur s'authentifie
  self.user.one("login", function(data) {
    $.extend(self.user, data.user)

    // 4b. déclenche un événement load après une authentification réussie
    self.trigger("load", data.view)

  })

})

Le code initial d’applications avec authentification utilisateur est en fait une chose assez complexe à faire, mais le cheminement ci-dessus est assez lisible.

API

L’API Riot est composée de 3 choses: une bibliothèque d’événements, un moteur de templating et une système de routage.

Evénements

Le système d’événements Riot est sur de nombreux points similaires à celui de jQuery mais il y a deux différences significatives:

1) Il n’y a pas d’objet Event car cela n’est pas pertinent en dehors du DOM.

2) Vous pouvez déclencher et recevoir des arguments d’événement sans les encapsuler dans des Arrays.

riot.observable(el)

Donne la fonctionnalité d’Observateur à l’objet donné el ou si l’argument est vide, retourne une nouvelle instance observable. Une fois cela fait, l’objet est capable de déclencher ou de réagir à des événements. Par exemple:

function Car() {

  // Rend l'instance Car observable
  riot.observable(this)

  // réagit à l'événement 'start'
  this.on('start', function() {
    // moteur démarré
  })

}

// crée une nouvelle instance Car
var car = new Car()

// déclenche l'événement 'start'
car.trigger('start')

el.on(events, callback)

Ecoute une liste d’événements events (séparés par des espaces) et appelle la fonction callback chaque fois qu’un de ces événements est déclenché.

// écoute un unique événement
el.on('start', function() {

})

// écoute plusieurs événements, le type d'événement observé est passé en argument de la fonction callback
el.on('start stop', function(type) {

  // type is either 'start' or 'stop'

})

el.one(event, callback)

Ecoute l’événement event et appelle la fonction callback la première fois, après quoi les événements suivants sont ignorés.

// appelle la fonction une seule fois, même si 'start' est déclenché plusieurs fois
el.one('start', function() {

})

el.off(events)

Arrête d’écouter la liste d’événements events (séparés par des espaces)

el.off('start stop')

el.off(event, fn)

Arrête d’appeler la fonction fn lorsqu’un des événements de la liste events (séparés par des espaces) est déclenché

function doIt() {
  console.log('starting or ending')
}

el.on('start middle end', doIt)

// supprime l'écouteur d'événements correspondant aux événements start et end et à la fonction doIt
el.off('start end', doIt)

el.off(events)

Removes the given space separated list of event listeners

el.off("start stop")

el.off(event, fn)

Removes the given callback from the event array

function doStart() {
  console.info("starting")
}

el.on("start", doStart)

// remove a specific listener
el.off("start", doStart)

el.trigger(event)

Déclenche l’événement event sur l’élément el et appelle toutes les fonctions de callback associées

el.trigger('start')

el.trigger(event, arg1 … argN)

Déclenche l’événement event sur l’élément el et appelle toutes les fonctions associées avec certains paramètres. N’importe quel nombre de paramètres supplémentaires peuvent être fournis aux fonctions de callback.

// écoute l'événement 'start' et attend des arguments supplémentaires
el.on('start', function(engine_details, is_rainy_day) {

})

// déclenche l'événement start avec des paramètres supplémentaires
el.trigger('start', { fuel: 89 }, true)

Templating

Riot a un système de templating exceptionnellement rapide pour prendre votre balisage HTML et le peupler avec vos données applicatives.

riot.render(template, data)

Prend en paramètre un template et retourne une String où tous les labels entre accolades sont remplacés par les données correspondantes. Par exemple:

// rendu simple
riot.render("<h1>Hello {name}</h1>", { name: 'John' })

// rendu avec des objets imbriqués
riot.render("<h1>Hello {user.name}/h1>", { user: { name: 'John' } })

Les deux retourneront <h1>Hello John</h1>. Le template ne peut pas contenir de logique, pour de multiples raisons.

riot.render(template, data, true)

Même chose que riot.render(template, data) mais toutes les Strings dans les données data sont échappées comme ceci:

Cela empêche les failles XSS sur les données passées. Utilisez cette méthode si les données sont fournies par des utilisateurs ou si vous n’avez pas de contrôle sur les données passées. L’inconvénient est que cette méthode est environ 15 fois plus lente que son alternative sans échappement.

// returns: "<h1>Hello &lt;freak&gt;</h1>"
riot.render("<h1>Hello {username}</h1>", { username: '<freak>' })

riot.render(template, data, fn)

Fournit une fonction personnalisée pour transformer les données data passées. Par exemple:

// le caractères @ n'est pas autorisé dans le nom d'utilisateur
riot.render("<h1>Hello {username}</h1>", { username: '@lolly' }, function(str, key) {
  if (key == 'username') return str.replace("@", "")
})

Routage

riot.route(to)

Change l’URL du navigateur et notifie tous les gestionnaires d’événements déclarés avec la méthode riot.route(callback) ci-dessous.

riot.route("#!/customers")

riot.route(callback)

Exécute la fonction callback donnée quand l’URL change (via le bouton Précédent) ou quand la méthode riot.route(to) est appelée. La fonction est également appelée une seule fois au chargement de la page – Riot s’assurer que cela survienne de manière homogène entre les différents navigateurs.

riot.route(function(hash) {
  // hash is a shortcut to location.hash
})

Voyez comment le routage est implementé sur notre application de démo.

Le bouton Précédent est supporté sur les navigateurs supportant history.pushState. Cela inclut tous les navigateurs excepté IE9 et versions antérieures. Sur IE9, cette fonctionnalité est dégradée et retourne simplement à la page précédente en ignorant les changements au hash de l’URL location.hash.

Extensions

Dans l’exemple ci-dessus, la méthode backend.call() retourne une interface Promise qui est créée avec l’astuce suivante sur riot.observable :

function Promise(fn) {
  var self = riot.observable(this)

  $.each(['done', 'fail', 'always'], function(i, name) {
    self[name] = function(arg) {
      return self[$.isFunction(arg) ? 'on' : 'trigger'](name, arg)
    }

  })

}

C’est une implémentation générique du pattern observateur dont vous pouvez bénéficier dans n’impporte quelle application JavaScript, pas seulement dans des configurations MVP.

Il n’y a pas de mécanisme spécifique d’extension dans Riot. Je pense que de simples fonctions à copier/coller sont les meilleurs composants réutilisables dans le monde JavaScript. Riot lui-même n’a que 3 fonctions. Elles étendent toutes l’espace de noms $ puisqu’il existe déjà sur la plupart des sites web (il est créé à la demande s’il n’existe pas) et que ce n’est pas cool d’assigner des variables globales.

Il y a une tendance regrettable à écrire du code tout-fait par-dessus des fonctionnalités simples (options, dépôts de modules, systèmes de build etc…) alors que tout ça pourrait être exprimés avec juste une fonction. Les fonctions simples sont utilisables partout.

J’adorerais voir quelque-chose comme Gist mais avec plus d’aide à la découverte (recherche, étiquettes etc.). Une grosse masse de fonctions réutilisables que vous pouvez coller dans vos propres projets, peut-être en les modifiant un peu pour coller à bos besoins. Que quelqu’un fasse ça pour nous, s’il vous plaît!

Conclusion

Les applications Riot sont plus petites et elles sont écrites en JavaScript basique ou en jQuery. La logique métier est complètement séparée et a une belle API. Toutes les fonctionnalités aurout de l’API sont dans des modules isolés et peuvent être développées indépendamment. L’API peut être exécutée et testée côté serveur, et l’application est rapide grâce à une architecture simple et un templating sans logique.

Tous les concepts ci-dessus sont bien documentés dans l’application de démo. C’est un panel d’administration dont vous pouvez vous servir comme point de départ.

Cette documentation était une introduction haut niveau à la programmation JavaScript modulaire mais il s’agit d’un processus en cours. La prochaine mise à jour donnera plus de détails sur les sections API, les tests, le build et le déploiement.

Liens

[1] MVP passive view

[2] Riot templating is Fast

[3] jQuery API implementations: Zepto, Minified.js

[4] Usage statistics and marketshare of JQuery for websites