We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Backbone is supposed to give me structure, but everything is still just a mess

00:00

Formal Metadata

Title
Backbone is supposed to give me structure, but everything is still just a mess
Title of Series
Number of Parts
150
Author
License
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
Having worked on several large-scale JavaScript applications built with Backbone we have seen many of the problems new teams experience with the library. In our projects we have hit on lots of issues, done a lot of strange things and learned a great deal. In this presentation we try to distill our experiences down to a few simple points that are important to consider when working with larger JavaScript applications based on Backbone. We have found several patterns that have increased the structure, maintainability, reusability and testability of our applications. In this talk we will present the most important of these and show you how to incorporate them into your own code. The primary focus in the presentation is applications built with Backbone, but several of the issues we raise are equally important in all large-scale JavaScript application. Among other things we will talk about reuse, plugins, memory management, how to use models and views, and lots more.
31
59
Thumbnail
1:00:41
89
Thumbnail
1:00:33
90
Thumbnail
1:00:33
102
Mobile appData structureEmailModel theoryEndliche ModelltheorieView (database)Observational studyLine (geometry)Data structureRange (statistics)Library (computing)Attribute grammarCartesian coordinate systemPhysical systemBlogConnectivity (graph theory)Set (mathematics)View (database)LogicGroup actionServer (computing)Functional (mathematics)Web pageLatent heatSingle-precision floating-point formatElement (mathematics)File viewerWeb browserDependent and independent variablesBuildingCodeGame controllerEndliche ModelltheorieBlock (periodic table)outputCuboidDiagramCodecLocal ringState of matterMobile appProteinProjective planeDebuggerMathematicsInformation technology consultingModel theorySoftware developerTwitterFisher's exact testEvent horizonFeedbackBitMaxima and minimaXMLUML
LogicModel theoryRouter (computing)Uniform resource locatorDiagramComponent-based software engineeringEvent horizonExecution unitVolumenvisualisierungFunction (mathematics)View (database)Electronic meeting systemGroup actionDatabase transactionMechatronicsLogicProcess (computing)MathematicsState of matterSoftware testingElement (mathematics)Game controllerWeb pageMereologySampling (statistics)Multiplication signBuildingBlock (periodic table)Event horizonObservational studyCartesian coordinate systemView (database)Model theorySystem callConstructor (object-oriented programming)Source codeSound effectInstance (computer science)CodeRouter (computing)Attribute grammarMobile WebInformationServer (computing)Database transactionEndliche ModelltheorieDependent and independent variablesType theoryQuicksortUniform resource locatorObject (grammar)
Execution unitProduct (business)Model theoryView (database)Function (mathematics)View (database)Web pageProduct (business)Heegaard splittingSound effectService (economics)Template (C++)Model theoryLoop (music)VolumenvisualisierungAddress spaceComplex (psychology)Connectivity (graph theory)Validity (statistics)LogicEvent horizonEstimatorSoftware developerData structureGraph coloringExistential quantificationAttribute grammarFlow separationProjective planeCodeRight angleArmEndliche ModelltheorieState of matterFunctional (mathematics)Direction (geometry)JSON
CodeInheritance (object-oriented programming)Object (grammar)SpacetimeSynchronizationRelational databaseConstructor (object-oriented programming)Execution unitParameter (computer programming)CodeFormal languageSoftware developerPattern languageDatabase transactionModel theoryMessage passingProduct (business)Core dumpPrototypeServer (computing)Email1 (number)ParsingLine (geometry)AreaLevel (video gaming)Attribute grammarLibrary (computing)Theory of relativityData structureConstructor (object-oriented programming)Dependent and independent variablesParameter (computer programming)Software bugBitObservational studyCartesian coordinate systemView (database)Router (computing)Complex (psychology)Connectivity (graph theory)Local ringInstance (computer science)Plug-in (computing)Inheritance (object-oriented programming)Object (grammar)Staff (military)Process (computing)Template (C++)NamespaceData storage deviceMultiplication signDirected graphRoutingEndliche ModelltheorieAbstractionMereologyGroup actionMaxima and minimaSlide ruleDifferent (Kate Ryan album)Internet service providerSynchronizationVolumenvisualisierungFunctional (mathematics)Computer animation
Component-based software engineeringPhysicsCodeFunction (mathematics)Endliche ModelltheorieEvent horizonMixed realityError messageComputer fileData structureMechatronicsBootingDynamical systemTemplate (C++)VolumenvisualisierungFunctional (mathematics)Pattern languageComputer fileCartesian coordinate systemTemplate (C++)Connectivity (graph theory)Validity (statistics)Ocean currentRule of inferenceModel theoryWeb browserData structureView (database)CodeEndliche ModelltheorieHand fanTesselationProjective planeModule (mathematics)Attribute grammarWebsiteMobile appCloningInstance (computer science)Library (computing)Decision tree learningStructural loadWeb pageSoftware developerCore dumpObject (grammar)Software testingEvent horizonMereologyPlanningFood energyProduct (business)Uniform resource locatorNamespaceScripting languageSemiconductor memoryPlug-in (computing)Service (economics)Letterpress printingInheritance (object-oriented programming)BootingComputer animation
Cartesian coordinate systemModel theoryModule (mathematics)Attribute grammarSingle-precision floating-point formatFunctional (mathematics)Computer animation
Maxima and minimaView (database)Line (geometry)Attribute grammarTrailSoftware developerSystem callModel theoryLoginComputer configurationDatabase transactionVideo gameJSON
Cartesian coordinate systemPattern languageSoftware developerData structureView (database)Multiplication signCodeSampling (statistics)Software testingFront and back endsComputer animation
View (database)LogicComponent-based software engineeringModul <Datentyp>Data structureData structureRule of inferenceComputing platformView (database)Element (mathematics)LogicPlug-in (computing)Web browserSoftware testingBitConnectivity (graph theory)Dependent and independent variablesModule (mathematics)NamespaceCartesian coordinate systemCodeJava appletProjective planeSoftware frameworkAbstractionLevel (video gaming)Doubling the cubeProcess (computing)Context awarenessGame theoryScripting languagePattern languagePresentation of a groupSoftware developerOpen setComputer animation
XMLUML
Transcript: English(auto-generated)
Hi everyone. So let's get started. You don't have... She's working on it, so... Do we have... Oh. I have some feedback here.
Yeah. It's okay now? Yeah, so today we're going to talk a little bit about our experiences using Backbone. We've been working on Backbone projects for a couple of years. Quite a lot of them. And we have seen a couple of things that have improved the structure of our applications.
So we'll try to just take the essence of that. And we're going to go through them now. But first of all, my name is Kim. I work at Beck Consulting here in Oslo. And I mostly work on front-end stuff.
Yeah, my name is Hans. I'm also from Beck Consulting. I'm working mainly on mobile application development. So Backbone is a library that has less than a thousand lines of code. It's become really popular these last few years.
And we see them used by quite a lot of big companies in Norway. And we think that one of the reasons for this is that you can use it for quite a range of applications. You can have something like Disqus, which is a third-party commenting system that you can, for example, include on your blog, as we have done in Beck.
So here you have JavaScript that has to run in someone else's site. You can have something like Inatur, which is a page for fishers and hunters here in Norway. They send most of their HTML from the server, and then they use JavaScript to add a lot of functionality on the front-end.
And you can also have something like Trello, which is a full-fledged single-page application. So they send just the basic HTML from the server to the browser, and then they use JavaScript for everything else. So Backbone is used in a range of applications.
And you can kind of say that Backbone is good practices in a set of reasonably small components. And they have a goal of improving the structure of your application, or of your JavaScript. So the quote is from Jeremy Ashkenaz, the creator of Backbone. He says that the goal of Backbone is to create this minimal set of data structures
for creating JavaScript applications. But Backbone doesn't get you there all alone, and that's why we're going to tell you a little about our experiences with using Backbone. So we're going to go through 10 problems or misunderstandings that we have seen,
how we have handled those, and how we do things now in our applications. So we're going to start off with talking about the responsibility of the building blocks. Backbone delivers some building blocks.
The first one is the model. The model in Backbone is supposed to communicate with the server. It contains logic for manipulating the data it gets from the server, and it doesn't do anything on the DOM.
One thing, if you are used to using jQuery before, you kind of are used to putting the state in the data attributes in the DOM. You should think about moving that state down to the models instead. We're going to get back to that later on.
The collection is responsible for a set of models. It communicates to the models and manipulates the models. It communicates also to the server. You can get a collection from the server, an array for example, and the models communicate back.
It would contain functions to manipulate its data, like add, remove, and find stuff. You can also put your business logic there. It has no knowledge of the DOM either. The view is the one that is responsible for the DOM,
and each view has one specific HTML element, and it will control that element and all of its children. We can look at an example here. If you see the Tweet to Superheroes box here, that could be a backbone view.
The view would then control the title and the input box. If we put that view into our diagram here, we can see that the view renders the HTML, and it listens to events on the DOM.
It also gets its data from the collection or a model or both, and the model or collection talks back to the view when they change their data. One thing we like to do in our application is that the view shouldn't contain any business logic.
You should put the business logic down into the collection or a model or some other JavaScript object. The router is the last building block that Backbone provides, and it's responsible for changing the state based on URL changes.
Basically, if the URL changes, you would maybe switch out the view in the DOM, for example. Events is something that is an important part of how you communicate in the Backbone application. All the Backbone building blocks that we talked about
have events built in them. We can look at an example here. If you have a user in your application that extends the Backbone model, you could listen to it by, say, user.onChange, and then you can do a callback when the user changes.
One of the main problems we've seen in a lot of our Backbone code and a lot of the code we've looked at is that there's too much stuff going on in initialize. Here's an example of a user view.
At the top of the initialize function, our constructor, we say that we want to create an instance of the user model. We then call fetch on the user model, so we do an Ix request to the server to get user information. Then on success, we render the view.
The problem here is that if we create an instance of the user view, for example in a test, it will be impossible for us to get access to the user, or it will at least be quite difficult to get access to the user because the user is both created and called fetched on.
What we want to do is to have control of the user. For example, we can inject it into the user view. Now we have more control. This is far easier to test. There's still a couple of problems though. One thing is that we are rendering our view on success.
In Backbone, the user has a lot of events built in, so we can listen for, for example, changes to the user and then render. Now that we're sending in the user, we can then listen for changes also when there's changes after we created the user view and then render the page. We can do that by something like this, for example.
We say that every time the user changes, we want to render the page. We're still calling fetch, and I think that's a bad side effect when creating an instance of something to also do an IX request. What we want to do is to push that fetch out of the constructor.
Now we have a reasonable simple constructor. We do this in almost all of our initialized methods. We only set the models and collections, and we start listening for events. Then it would be something like the router, who is responsible for creating an instance of the user model and actually creating the user view and injecting the user.
It's also the router which calls fetch on the user model. Now we have full control of the user view for testing. It's easier to reuse in other contexts. As you can see here, we also pass in EL, which is the HTML element of the view.
Now the view is not responsible for saying where it's supposed to be on the page. We tell that to the view. You're going to render into this place in the DOM. Again, it's easier to test, and it's also easier to reuse. It's not all the time you need to reuse a view, especially large views,
but this is a nice step either way. If we place this into our diagram, we can see that the router is now responsible for working with the view and working with the models and collections.
We already talked about the business logic in views. If you start making a view, where you usually start actually, when you just mock your data and you start creating a view, you can end up with something like this. I don't know about you guys,
but I don't like to read code like this because it's hard to read. When you start looking at this view, it's kind of, what does it do? Oh, okay, it sorts by two different attributes. It then merges the data together and then puts the thing into the DOM. What we want to do is to push this logic down
to the collection instead. You can say something like this. You can say, this.transaction gets sorted by date and type. Remember that when you are developing views that you should put the logic down into the collection or some other JavaScript object instead.
A thing that always tends to happen is that the views just grow and grow and become really complex. This is an example of the project I'm working on right now. We have a page with three products. At the beginning, you just choose one of the products and then we went to the next page.
After a while, we started adding more functionality to this. You could choose the product. You could choose how many children you wanted to ensure. You could take off some features you wanted to include. We had some validation. There's a lot of stuff going on here. If you just look at one thing here,
the views always tend to start out quite small, but they just grow and grow and become more and more complex. They become really hard to understand and that's probably one of the main problems here and also that they become difficult to test. We can have something like this.
We have our products view, which is created from a backbone view. We then do what we said here in the initialize. We send in our products collection and we start listening for an event. We render the page. We don't need to look at that now, but here in choose product, which we will hit when we click on one of the product buttons,
we will here need to do something on the product. How do we find that product? Now we need to go look for something in the DOM to know which product was clicked. We could do something like this.
We don't really want to have these data attributes in the DOM. There's more state in the DOM and there's more complexity here. Here, this is the way to find a product. You can now see that we take the product ID and we go look for it in the products collection and then we can do something on the product.
The solution to this is to split your views into subviews. This is a really nice way to make your views smaller and to move the complexity away from this large blob of code. We can have something like this. The black right there was the products view that we just looked on and now we have created three subviews,
one for each product. We can have one view per model in the collection. If we look here at the products view in render, we can see that we first compile our template and put it into the DOM. We then loop through all of the products
and create a product view where we inject the product. Then we can render the product view and in the end we can take all of these product views and put them into the DOM. The nice thing now is that the product view for a single product has less complexity.
Now we say that we listen for a click on that product and in choose product we already know which product was clicked so we can just start working on it directly. Of course you need to think about performance here. You can't do this if you have a collection with a thousand models.
It depends on when you should use this, but if you have reasonably small collections, this is a great way to move some of the complexity often. Also it depends on the amount of logic you need for each model. If you have a lot of complexity, a lot of things you need to listen for, for example a couple of events,
and you need to do a lot of stuff when some things clicked on, having a subview is really nice. What we tend to do in our products is to write for structure and then to try to optimize if we see that there's a problem. Very often we don't see a lot of problems related to this
because just working with the DOM and everything is so expensive from before. Another way you could use subviews is to simplify a large view by splitting it into several subviews. This is almost like having one subview per model in a collection.
Here for example we have a view that takes in two models, an address model and a person model. Before this was one complex view and now we have split it into two separate smaller views. Here we can just pass it in directly. We create the address view and we create the person view.
Then when you go render this large view, we first put it into the DOM, just the scaffolding around these two views, and then we can render each of these views into the DOM. This is kind of a problem when you code in every language.
If you have many developers on the team, your code tends to duplicate code. You have seen this render method in previous slides. Basically what you do in a render method in Backbone, you merge some data based on the collection or model
and then you put that data into the view. This is a simple example, but it's kind of just a way of thinking. If you do something like this instead, it's easier to read and you don't repeat yourself that often.
To get here you use inheritance in JavaScript. What we tend to do in our application is to make a base of every component that Backbone provides. You make a base view, base collection and base model, and a base router.
Now you can say something like this. You merge the data and you render out the data to the template. Another cool thing about this is if you want to switch out Mustache, which is used here to, for example, Hogan,
you can just switch this one line because Hogan and Mustache use the same syntax when you write the templates. It's easier to switch out things when you use abstractions. There are a couple of things that you should be aware of when using inheritance.
Too many levels of inheritance is difficult to trace back in an application, so keep the levels of inheritance to a minimum. We tend to say that one level is enough. You don't have any nice way of calling a parent in JavaScript.
You do have a way, but it's ugly. You can only inherit from one object at a time. One thing we do in our application is to use mix-ins instead. Basically what you do
is to merge functionality together, two objects together. Say you had a pagination component, which is basically just have a next and previous, and you want your collection to have a next and previous method. Then you can do something like this.
You have a transaction collection and you use underscore dot extend to extend the transaction's prototype. Now you can do something like this, because the transaction's prototype now has next on it.
Sadly, we've seen that backbone plugins tend to look like jQuery plugins. That means that there's a couple of really good ones and a lot of really bad ones. We tend to say that you shouldn't pull in too large a plugin too early in your development,
especially if you're not used to backbone from before. You should really get to know backbone before you start pulling in these large complexities, because backbone itself is quite small. If you're grabbing a plugin that is twice the size, for example, that's a lot of complexity. You should really try to understand at least the value they add first.
We're going to show some... There's a couple of plugins following what we tend to think about as anti-patterns. I know a lot of other people don't think of them as anti-patterns. You can have something like a plugin overriding here at the backbone namespace.
Here we can see Backbone Local Storage that overrides Backbone Sync. The problem here is that Backbone Sync is actually at the core of what Backbone does. It's used in all of the models and collections when communicating with the server. Now you have something that has overwritten what it says in the backbone documentation.
This makes it difficult to get new people into the product and to understand what's going on, and also what happens if a plugin adds a complex sync and you get some subtle bugs there. I don't like having code overriding the core of the libraries I use.
You also shouldn't become too dependent on a plugin. We have seen a couple of reasonably large plugins where the development has stopped at least for months at a time, and that also has a lot of GitHub issues. They might seem really magical when you're getting started and you're having some kind of problems with Backbone you're getting just to know the library itself,
but this magic might be really easily destroyed. We tend to use plugins that follow the Hollywood principle. That means that you call into the plugin and you get a response from the plugin and you can use that response in some way instead of the plugin overriding your code
and calling back into your code and stuff like that. The question is also if you need the plugin, especially when you're new to Backbone, it takes some time to get used to the abstractions and the way of thinking, because a lot of us come from a jQuery background from before. If you use Backbone.Relational as an example,
a lot of people need nested collections or nested models. The thing is that Backbone.Relational is double the size of Backbone itself, so there's a lot of complexity. The question is, do you need all of this complexity
if you just have some simple problems? For example, you need one-to-many relations. For example, we have an inbox model here that has a messages collection on it. Here we can say in the constructor, the constructor and initialize is a little bit different in Backbone
because constructor is the one calling initialize. Here we say that we want to do something at the beginning of the instantiation of the inbox model. We want to create our instance of the messages collection and then we call, this is a way of calling super, so we say that we want to let Backbone continue with the constructor.
Then we have two important methods here. We have parse, which is called when you receive data from the server. All the data you receive, you will get in as the first argument here. The thing that you return from parse
will be set as attributes on Backbone, on the Backbone model, and to JSON is called the other way. When you send data to the server, Backbone calls to JSON and the response is sent to the server. In parse, we could do something like this. We have the messages array,
which we have received on the response, and we set that on the messages collection. Then, as we don't need to set this array as an attribute on the Backbone model, we can delete it from the response and then return. In 2.json, we do the opposite. We take the Backbone attributes,
we put back messages onto those attributes by calling 2.json here on the messages collection, and then we return the data. This is sent to the server. Another thing that tends to happen
when you start using Backbone is that you find it kind of cool and you start making models and collections and views and routers for every JavaScript you are creating in your application. Our recommendation is to think about if you need the functionality
that components give you. Take the model, for example. Do you really need your JavaScript object to have the model functionality? Often you might say you don't, so then you should think about using vanilla JavaScript instead.
What we did in our applications is to make a concept around this just to prevent us from always using a Backbone model or creating a collection. We call it simple components. It's kind of an attempt to make plugins more manageable.
We set some ground rules for what a component should really be. You should keep a component as small as possible. It should solve a really simple problem preventing duplication of code. It shouldn't have any dependencies at all,
but you can add some if you need them. It's kind of like the Unix philosophy. An example of a component that we use in our application is really just a clone of Backbone events. What we needed in our application
was a distributed way of communicating between objects that don't know about each other. Then we just made one instance of Backbone events and used that throughout our application. That's a simple component. It solves one problem for our application.
Another component that we use in our application is a validator component. You can say that this one uses the same pattern that Kim talked about earlier. Actually this one you have to call down on. Backbone model has a validation method
and you would basically just call this validation method from the Backbone model's validation method. Then you can just pass in any attributes and the validation rules. The nice thing about this is that this one works across any JavaScript object really. You don't need a Backbone model for this to use this.
Another example of a component that we made is the subview handler. It's a simple component. It solves a simple problem. It basically tracks your subviews in a parent view and you can call destroySubviews
when the parent view is destroyed. The nice thing about this is that you minimize the memory footprint in your application. A thing that we have seen and it'll be actually more important than we thought is just how we handle files and dependencies.
This is the current folder structure on the project I'm on. We have an act.js which just kick-starts the entire application. We have our components folder and our external libraries. The important thing here is the modules folder. Inside the modules folder
we have all of our modules. That just means some of the core things on our page. For example, payments, users, and stuff like that. This is usually a part of the size, a part of the application, a byte-sized piece of the application. These folders include all the files needed
for that piece of functionality. That can, for example, be a collection, a model, some templates, and the views needed to show that piece of the site. It can seem trivial, but the folder structure is actually quite important
when you're working on your application. It also makes it easier to create new functionality because you already have some ground rules for where you should place them and how you should work with your code. We prefer to have feature folders. We see a lot of people using views, models, and collections folders, but that makes it really hard to find
all the functionality needed for some little piece of the site. We collect modules into their own folders because we think that code that belongs together should stay close to each other in the code base. I've also tried to experiment with including my tests inside the same folder.
Now I have all my code for one feature inside the same model. It can also, for example, have folders inside it, but the main thing is just moving everything together. This works really well with RequireJS. RequireJS is a file or module loader.
That means you can dynamically load files in development, and it can also create one minified file for production. Here we can see an example. We see that in this file here we want to depend on Backbone. RequireJS fetches Backbone and hands it to us.
Now, instead of using Backbone from the global namespace, we actually say that we depend on Backbone and get it in here. It's really easy to see all of our dependencies. Then we can create a cart model and return it from this file. Now, if we, in the same folder, create another file
and say that we depend on cart in the current folder, it will go fetch this file, and if it hasn't loaded Backbone yet, it will fetch Backbone, and then it will return our cart here. Now we can create an instance of our cart model.
You now have far less need for globals, and this also makes dependencies really visible. That's a big plus from where we are often today. Where we don't really know what dependencies the file has, you have to go looking for it.
It's also far easier to see the need for having one file per object. For example, per model and per collection and per view. This makes handling templates really easy. There's a lot of plugins for loading and compiling templates. You can have something like a Handlebars plugin,
which Hans Magnus has created, where we can say here in RequireJS that we depend on the Handlebars plugin, and we want it to be applied to the payment file in the current folder. Here the plugin then goes looking for payment.hb, the Handlebars template,
and then it compiles the template and gives it in here. One of the cool things here is that this works really well when you're minifying your code because the plugin fetches the file and pre-compiles it into JavaScript. Then you don't have to do all of the compiling in the browser.
This works really well for mobile phones at least. In total, if you look at modules and RequireJS together, let's say that we're creating a payments view. Here we can say that we depend on Backbone, we depend on payment view in the current folder, and on the payments template in the current folder.
If we had had this file spread out across our repository, this would be really difficult to go looking for them. This makes it really easy to just move them around, to rename stuff and things like that. Another thing about modules is that each module should be self-contained.
If you place it in another application, it should actually work. Just remember that they should be closed into a single piece of functionality. One thing that we have some quirks or things that we don't like with what Backbone do,
and we just encourage you to don't blindly follow Backbone conventions. One of the things that we tend to don't follow is the automatically setting of collection and model,
because when you create a view in Backbone, if you pass it in an attribute collection or model, it automatically sets the model or collection on this. It's kind of a neat feature if the views are small, but they tend to grow larger, and it's kind of hard to know what that collection is.
Is this collection transactions, or is it one transaction? It's kind of hard keeping track of what it really is. If you want to find this out when you use this one,
you have to console log. It's really hard. Do something like this instead. Take in an option, call the thing for what it really is. It's one line more of code, but it's much more readable for the next developer that comes after you.
Be explicit is sometimes better than being implicit. We have looked at a lot of things that might seem trivial or easy. At least a lot of backend developers tend to think so, because they follow a lot of the patterns in their code on the backend.
But we experience problem with this all the time. We do it all the time ourselves, and we've also helped out in a lot of applications, and we see a lot of the same things going on. Often structure is just about fixing a couple of those small things, especially injecting stuff, instead of creating it inside, for example, a view.
That helps a lot, especially if you want to try to start and test your backbone code. I see a lot of people struggling with testing, because they try to do everything inside, for example, a view, and that makes testing really hard. Often there's just a couple of minor things you need to do to have a far better structured application.
Some of the most important things that we've seen is to simplify your views with subviews. Using subviews is a great way of having simpler views, and you should also keep your business logic out of views. It's so easy, because you're used to working
with jQuery, for example, so it's very easy to just push a lot of logic into your views. So it's really important to try to get that stuff down into the model or into a collection, especially if it's stuff that's not working on DOM-related stuff. We tend to be aware of plugins,
and only use plugins that follow our rules for them, so that means that we have to call them and get a response instead of them grabbing some of the backbone namespace and stuff. I know a lot of people like those plugins and I think that's okay, but you should be aware of why
that might be a problem. We tend to use components instead, so just this concept of having small reusable pieces of pure JavaScript. Try to build decoupled and focused modules. This really helps when your application grows in size.
The thing that has really helped us with our structure is to focus on testing, so really try to be strict about it, especially the first couple of weeks. We see a lot of people giving up after a couple of days, because they're trying to test a lot of the code that they have already written from before, and this is really hard,
because you tend to follow a couple of anti-patterns, like not injecting stuff, especially not injecting your HTML element into the view, or injecting your collection into the view, for example. All in all, these are our experiences with how to create a more structured backbone application.
Any questions? It's really hard to see here, so if you have any questions, you need to... I can't hear you.
The question is, what platforms or frameworks are we using to test our backbone code? Right now, we're using Jasmine on my current project. That would be because we started with... We had a lot of Java stuff on the backend, and we couldn't use Node, so we had to use something that could run only in the browser.
I often use Jasmine or Mocha. I've also used Bester.js a bit. Now I've started using Karma as a test runner, so Karma is responsible for opening browsers and running all my tests in all those browsers, so I think that works really well.
If you use Karma, you are kind of dependent on Node, so if you can't be... I really like Mocha. I think that's probably the best testing framework right now, and I also like Karma and TestM as test runners. Any other questions?
No? I might... I hope someone disagrees with us, and if you do, please come talk to us about it. We really want to learn more about how other people experience using Backbone, because we know that Backbone is quite a low level of abstraction,
so you have Ember and Angular and all those that have really far more powerful abstractions, but they are also larger in size, so we don't tend to say use Backbone or use Angular. You should really look at what your needs are. So if you disagree, or if you agree, come talk to us. This is the URL for the presentation.
So, thanks! Thank you.