ENLARGE YOUR
BACKBONE PROJECT
COMMENT ORGANISER SON PROJET DE FAÇON MODULAIRE ?
PrésentéparNicolasCARLO( )etFabienBERNARD( )@nicoespeon @fabien0102
KIKON EST ?
NICOLAS CARLO
VPofEngineering
FABIEN BERNARD
CTO
SAYKOIKON FAIT ?
Jeu socialsur le thème du vin dans lequelon peut
acheter en vrailes bouteilles que l'on produitvirtuellement
En HTML 5…‘‘full-stack JavaScript’’
Backbone.js + Marionette
Node.js + MongoDB
Grunt, Mocha, Yeoman, …
LES GARS, CE SOIR ON FAIT UN PROTO !
- UN MANAGER UN PEU TROP CONFIANT
//Probablementàl'arrache,dansun`main.js`FTW
//Note-pasbesoinderoutagepournousdonconfaitsans=)
$(function(){
//(…)
//Onpréparenosbouteilles
varbottlesModel=Backbone.Model.extend({...});
varbottlesCollection=Backbone.Collection.extend({...});
varbottlesView=Backbone.View.extend({...});
varbottlesCollectionView=Backbone.View.extend({...});
//(…)
//Etoninitialisetoutlemonde!
varmyBottlesList=newbottlesCollection();
myBottlesList.fetch();
varmyBottlesListView=newbottlesCollectionView({
LE LENDEMAIN
- AKA THE HANGOVER
$(function(){
//(…)
//Onpréparenosbouteilles
varbottlesModel=Backbone.Model.extend({...});
varbottlesCollection=Backbone.Collection.extend({...});
varbottlesView=Backbone.View.extend({...});
varbottlesCollectionView=Backbone.View.extend({...});
//Onpréparenosbâtiments
varbuildingsModel=Backbone.Model.extend({...});
varbuildingsCollection=Backbone.Collection.extend({...});
varbuildingsView=Backbone.View.extend({...});
varbuildingsCollectionView=Backbone.View.extend({...});
//Onpréparenoscépages
varcepagesModel=Backbone.Model.extend({...});
varcepagesCollection=Backbone.Collection.extend({...});
TIENS, C'EST DRÔLE...
parfois çaplante, parfois çapasse…
quand j'enlève ce boutde code y'atoutquiplante !
je retrouve plus où on acodé cette boite de dialogue ?!
faudraitp'têtr qu'on mette des tests unit... oh wait!
le soleilse lève dehors =)
IL FAUT S'ORGANISER!
YAKA SÉPARER LES
FICHIERS PAR TYPES
CONCRÈTEMENT, ÇA DONNE QUOI ?
app/
main.js
models/
bottles.js
buildings.js
collections/
views/
tests/(parce-qu'ilfautpas déconner non plus)
THE GOOD PARTS =)
On yvoitplus clair quand même !
Les tests sontisolés
Facile de trouver des exemples pour cette archi
THE BOF PARTS =/
L'achitecture du code ne reflète pas vraimentnos ‘‘modules’’
Etmon style, ilestpas modulaire mon style ?
Pis faudrapas oublier :
beware ladépendance entre les ‘‘modules’’
LES QUESTIONS À SE POSER
- MERCI ADDY OSMANI O/
Aquelpointce module estinstantanémentré-utilisable ?
Mes modules peuvent-ils exister indépendamment?
Mes modules peuvent-ils être testés indépendamment?
Mon application n'est-elle pas trop étroitementliée ?
Siune partie de mon applifail, est-ce-que touts'écroule ?
NOTRE SOLUTION
(PROPOSÉE)
LA THÉORIE
Source- (inspiredbyN.Zakas)http://scaleapp.org/
UN DOSSIER = UN MODULE
- ETPICÉTOUT !
app/
main.js
main.less
modules/
bottles/
bottles.js
bottles.less
models/
collections/
views/
bottles.views.composite.js
bottles.views.item.js
templates/
tests/
EN PRATIQUE
LES ÉLÉMENTS DE BOTTLES
//bottles.model.js
//Uneseuledépendance->ApplicationCore
define(["app"],function(app){
returnBackbone.Model.extend({...});
});
//bottles.views.item.js
//Uneseuledépendance->ApplicationCore
define(["app"],function(app){
returnBackbone.Marionette.ItemView.extend({...});
});
EN PRATIQUE
LE MODULE BOTTLES
//bottles.js
define([
"app",
//Lemodèle
"bottles/models/bottles",
//Lesvues
"bottles/views/bottles.views.item"
],function(app,Model,ItemView){
//Initialiselemoduleaveclesméthodesdebase.
varBottles=app.module();
//OnspécifienosAPI
Bottles.Model=Model.extend({...});
Bottles.Views.Item=ItemView.extend({...});
EN PRATIQUE
LE MAIN.JS
//main.js
define([
"app",
//Lesmodules
"bottles/bottles.js"
],function(app,Bottles){
//Initialiselemoduleaveclesméthodesdebase.
varmyBottlesList=newBottles.Collection();
myBottlesList.fetch();
varmyBottlesListView=newBottles.Views.Collection({
collection:myBottlesList
});
myBottlesListView.appendTo("#bottom-bar");
});
UN MODULE C'EST COMME UN ENFANT
- MERCI MONSIEUR ZAKAS O/
Les modules doiventgarder les mains dans leurs poches
On ne touche pas au DOM des autres
On ne touche pas aux méthodes des autres
Les modules demandent, ils ne prennentpas
Les modules ne laissentpas traîner leurs jouets : pas de
variables globales, encapsulation
Les modules ne parlentpas àdes étrangers : on ne parle pas
directementaux autres modules
NOS OUTILS
REQUIRE.JS
GESTION DE DÉPENDANCES + OPTIMIZER AVEC R.JS
Détermine les dépendances de chaque boutde code
Re-compile ces dépendances en un seulfichier JS optimisé
NOM DE CODE BRAIN.JS
NOTRE PATTERN MEDIATOR À NOUS
Tour de contrôle des modules
Centralise lacommunication = découplage des modules
Écoute les événements intéressants -Backbone.Event
Trigger d'autres événements pour déclencher des actions
MARIONETTE.JS
ENTRE AUTRES UTILITAIRES
Boite àoutilindispensable pour gérer des vues de plus en plus
complexes
Abstraction + cache de l'UI
Simplifier laconf.
Enregistrer de requests pour découpler son code
Sinon y'aChaplinaussisibesoin d'aller plus loin
ABSTRACTION + CACHE DE L'UI
<divclass="builds__menu">
<ulclass="builds__menu__tabs">
<lidata-ui="tab">Bâtiments</li>
<lidata-ui="tab">Décorations</li>
</ul>
</div>
<!--(…)-->
returnBackbone.Marionette.ItemView.extend({
ui:{
"tab":"[data-ui~=tab]"
},
events:{
"click@ui.tab":"switchTab"
}
//(…)
highlightTabs:function(){
this.ui.tab.each(function(){
//Dosomethingawesome!
});
SIMPLIFICATION DE LA CONF.
returnBackbone.Collection.extend({
events:{
"click":"displayName"
}
appEvents:{
"bottles:do:setName":"setName"
}
//(…)
initialize:function(){
Marionette.bindEntityEvents(this,app,Marionette.getOption(this,"app
Events"));
}
setName:function(appellation,name){
ENREGISTRER DES REQUESTS
returnBackbone.Collection.extend({
requests:{
getCategories:function(){
//Retrievecategories…
returncategories;
}
},
//(…)
initialize:function(){
app.reqres.setHandler("builds:getCategories",this.requests.getCategori
es,this);
}
//Pendantcetemps,ailleursdanslecode
varbuildsCategories=app.request("builds:getCategories");
//(…)
AXES D'AMÉLIORATION
Améliorer l'init. des modules dans le main
Multiples Brain.js, parce-que çagrossitvite
Différents ‘‘channels’’ pour les événements
Des suggestions ?
Comment organiser un gros projet backbone

Comment organiser un gros projet backbone