11 ms·
Migrating a large JavaScript project from DOM spaghetti to Backbone.js
- mcs 14y agoAwesome. I would suggest using something like https://github.com/afeld/backbone-nested https://github.com/afeld/backbone-nested to enable a.get('foo.bar.foo') so you don't have to a.get('foo').bar.foo and suffer undefined errors.
- romain_dardour 14y agoOr use coffeescript and write a.get('foo')?.bar?.foo
- codewright 14y agohttp://en.wikipedia.org/wiki/Monad_(functional_programming)#The_Maybe_monad http://en.wikipedia.org/wiki/Monad_(functional_programming)#... It shouldn't have to be a library with custom handling of the edge cases like that :|
- oinksoft 14y agoIt is pretty common to use a function like this when digging into objects in general JS code: function get(p, o) { var parts = p.split('.'); for (var i = 0, l = parts.length; i < l; i++) if (o.hasOwnProperty(parts[i])) o = o[parts[i]]; else return undefined; return o; } var o = { a: { b: { c: 1 } } }; console.log(get('a.b.c', o)); // 1 console.log(get('no.way', o)); // undefined I'd be more likely to reuse something like that because it's already useful in the codebase than bringing on another library. However, I am speaking out of ignorance, as it appears that the library you cite does a lot more than this simple thing: https://github.com/afeld/backbone-nested/blob/master/backbone-nested.js#L202 https://github.com/afeld/backbone-nested/blob/master/backbon... In any case safe lookup methods are very useful!
- codewright 14y agoNot very composable or nice. Bespoke solutions are besides the point and the very thing I was decrying.
- deleted 14y ago[deleted]
- jQueryIsAwesome 14y agoYeah, is one of the things I don't like about JS. The typeof operator should be able to handle those cases. Or a new operator that returns a boolean would be nice. if(defined jQuery.unknown.propierties)
- bryanh 14y agoThis is wonderful! I especially like the detailed coverage of Backbone views. They tend to be the most perplexing part of Backbone (do I nest? how much? how do I track them? etc...) and you outlined your use case nicely.
- owenjones 14y agoAgreed. Even as someone who feels pretty comfortable in Backbone this was a good exploration.
- modarts 14y agoAs someone about to embark on a large-scale project re factoring to backbone: Thank you!
- typicalrunt 14y agoSeeing the slide about one file that had 8500 lines in it surprised me. Maybe it's a JS thing (I'm not one of those guys) but I've been pushed to make smaller files instead of one large god file. It's hard to traverse a file with that many lines in it, as well as do any meaningful diffs on it.
- FuzzyDunlop 14y agoI've encountered a few ~10K sloc files, in PHP. One ex-colleague preferred them, on the basis that "it makes it easier to use Ctrl+F."
- pserwylo 14y agoWe have some legacy files with > 20K in PHP. I'm yet to find a PHP IDE which will happily consume these files and let me work them. I just jump into VIM when I need to edit them. For arguments sake, I'm talking an IDE in the model of Eclipse/IntelliJ/Netbeans, not vim/emacs/etc. I'm aware that people have some pretty awesome configurations for such editors, but I'm for the most part extremely happy with IntelliJ.
- vidarh 14y agoWhat makes you keep it that way, given that breaking out large chunks and including the new files back in shouldn't be hard?
- pserwylo 14y agoEach file represents a module in our business management software (e.g. documents/contacts/memberships/events/etc). Historically, we have replace entire modules with ones that fulfill new/improved/different needs. For example, we have a module called "membership 3", because as we have obtained new clients, "membership" and "membership 2" just were not structured to do the things the new clients needed. When the company started, we were full of inexperienced devs with no official programming education/experience. Now we have a team that is more aware of things like design patterns. As such, the newer modules are easier to extend and add new features to, so we anticipate that rewriting entire modules should not be necessary when the newer versions need new features. So to answer your questions, we are just waiting for the old versions to die, and for somebody to pay enough for a job that we can rebuild the old module from scratch :) Of course, contributing factors such as time, blah, blah, man power, etc. come into play also. Always things that need to be done, never the time to do them.
- OriginalSyn 14y agoThanks Samuel, this was the best talk at the summit.
- hamdiakoguz 14y agoI clearly see that backbone version is better. But i wonder if is it just me that thinks there must be a better way than the event driven nature of backbone ?
- rhysbb 14y agothere are better frameworks out there for larger projects definitely - but event driven is the best way for larger projects.
- bjhoops1 14y agoGreat post! Only suggestion I might add as a helpful pattern would be leveraging Backbone.Events to implement a Mediator pattern for communication between Views. This is overkill for between Parent Views and SubViews, but I have found it to be very useful in facilitating communication between unrelated Views.
- rhysbb 14y agoReading this just makes me scared of Backbone for larger projects. Things like having to keep changes to models silent just because a view isn't ready? Backbone is all good and well for small projects, but I think it's be best to look elsewhere for a larger project. The problem is that backbone has a smaller learning curve so people try to get started with it, and it is better than nothing, but in the long run you'll just run in to more dead ends and spend more time on fixing things and getting around edge cases than if you went for a more fully fledged solution like http://emberjs.com http://emberjs.com or https://github.com/rhysbrettbowen/PlastronJS https://github.com/rhysbrettbowen/PlastronJS
- conesus 14y agoYou raise an interesting point. That technique was developed in response to a difficult part of the migration. I had stories coming in for subsequent pages of an rss feed, but I didn't want to re-render the story view until I had a chance to work with the un-rendered story views. I realize this can be a bit complicated, but at some point you'll be wishing you could just turn off an event from firing because it's interfering with a juggling act. This is what that technique is used for. But any project that reaches a certain scale will tend towards having some unfortunate ties between models that makes a more-than-ordinary transition hard to accomplish. It can be done, but I'm not quite there, and I suspect many other developers aren't either. This one's a stopgap.
- eggsby 14y agoI'd argue that the problems in large projects are primarily architecture problems, that backbone's philosophy of 'bring your own architecture' means how well an app is structured is entirely up to its authors rather than defined by library choice. Something like your plastronjs or emberjs are saying 'Here, do it like this'. Which is good. Sometimes. I've certainly run into many issues using backbone for moderately sized applications (form workflows, several different types of records, etc) but every time I get myself out of them I gain general javascript knowledge rather than domain specific knowledge about framework xyz. I'd much rather know how to effectively manage memory in javascript than how to use a particular framework.
- 14y ago
- lapusta 14y agoBackbone is a great framework and moved the industry forward a lot in terms of code quality. But there are definitely couple things broken, like Zombie/Ghost views - everyone(!) is making their own workaround. View part is too much DIY. Seriously, _.template is okay for views with no input and simple updates, but if you have heavy IO views become bloated. Check the wiki, there are 7 "yet another binding plugins". Make default one, and make it an option (view binding can be slow and not needed sometimes). Another DIY are models relations & nesting. These two additions wouldn't be big for the core, but they could really improve the ecosystem. Now you have to take in mind those third-party plugins people are using for these covering basic gaps.
- timc3 14y agoSo what do you suggest?
- riprock 14y agoI haven't used Backbone.js, but from what I've read there are extensions like Backbone.Marionette for better view and memory management. https://github.com/marionettejs/backbone.marionette https://github.com/marionettejs/backbone.marionette
- randall 14y agoAs obviously stated in other threads... I've moved to Angular. Their 'digest all the changes and update the dom once' makes a lot of sense... and it has basically inverse opinion from Backbone. (Backbone has lots of opinion about data / saving, while Angular has more opinion about binding and logic.)
- eta_carinae 14y agoEmber.js?
- lapusta 14y agoBackbone is an opinionated software, so it's hard to say if binding would be ever included. For developers I suggest to try some of plugins, which are listed on GitHub wiki in the binding section and also take a look at Knockout/Ember/Angular so at least you would know what other frameworks offer.
- salimmadjd 14y agoGreat post! I wish you had briefly talked about why you picked backbone over other options like AngularJS.
- conesus 14y agoI'll admit, partially it was because I was sitting next to Jeremy as he was pulling backbone out of the documentcloud workspace and into a soon-to-be-released javascript library. Otherwise, the community has embraced Backbone.js and, for better or for worse, you're swimming in the biggest pond. That means more community driven updates and support, as well as more competition to stand out from in the newest javascript writing convention.
- gambler 14y agoI never understood why people proudly boast about their past mistakes. Is it supposed to make their current achievements sound better? "Oh, we had 8500 lines of spaghetty JS code in one file, but we used AwesomeFrameworkX and it fixed everything!" For me, this doesn't make the framework sound more impressive, but rather undermines credibility of the author. How did it get to 8.5 lines? Did no one notice? Did no one care? Was every line necessary? Does having a file like that is really better than having some stuff handled on the server side? Was Backbone the only way to move forward?
- conesus 14y agoThe intention was to allow people to commiserate and understand that this happens to many code bases and there is a path out of the woods. As far as letting the file deteriorate to that length, NewsBlur was a side project of mine for two years. That's how long it took, and because I only had 45 minutes at a time (my commute) to work on it, large scale refactors were not a priority. And it took two years before I realized that NewsBlur would be sticking around and I should care for the code base. It was at that point that I began the process of refactoring the bejeezus out of it.
- tomkit 14y agoTotally agree. It shows more of the author's initial failings and then trying to generate buzz with hot HN keywords like 'backbone'. One file with 8500 lines could have easily been avoided with the module pattern either by handrolling it or using various libraries out there like requirejs, commonjs, etc.; backbone is not required.
- mattdawson 14y agoYou're only addressing part of the problem. File size is a much easier thin to fix than refactoring DOM bound soup.
- justinator 14y agoNo one's perfect and we all make mistakes, given the circumstances we find ourselves in - we all make choices with incomplete information. Admitting that there's a better way to do things is a good first step to become better. To share what you've learned is a sign of being humble.
- kylecordes 14y agoFrom the blog post and slides, it looks like this was a big improvement. But... You may find that moving to a higher level, more declarative solution (like Knockout) yields a considerable additional improvement.
- skeletonjelly 14y agoI thought Knockout and Backbone were two implementations fixing the same problem. Can you expand?
- rimantas 14y agoUnless something changed drastically changed in the last year my impression was this: Backbone helps you to fix problem, Knockout just hides it. I think some people just have a problem with backbone being too flexible, because it matches the name perfectly: it is just backbone helping you to solve problems you will have to solve anyway. Knockout feels more like exoskeleton — it may be very comfortable when you fit in, but as soon as you don't you are in a lot of pain.
- modarts 14y agoI could imagine data binding geting very hairy to develop more complex apps with.
- nateabele 14y agoWow. After using AngularJS for a few months, it's amazing what a nightmare it looks like to work with Backbone.
- randall 14y agoRight? Jquery DOM mess < Backbone < Angular.
- porker 14y agoPlease write your DOM -> Angular or Backbone -> Angualar follow up for this article - would love to see the difference. Like TodoMVC on steroids :)
- nateabele 14y agoSorry, my time isn't worth so little that I'm going to spend hours writing an article just to prove a point to a guy on HN, but here's an existing example: https://github.com/angular/peepcode-tunes/commit/87dfa695d9981b1fc439c6cf4ed32f77970faf8f https://github.com/angular/peepcode-tunes/commit/87dfa695d99... Diff stats: 360 additions, 636 deletions, on a total of 628 original lines of JavaScript (app + test code; deletions include redundant lines of template code).
- porker 14y agoThanks for your link. If your time's worth so much, why are you on HN spending time contradicting someone? Saving all your HN-time and writing an article to educate people would give greater value to your time and educate more of humanity...
- colin_jack 14y agoThinking that maybe the vague & snarky reply was both more enjoyable and quicker to write.
- ww520 14y ago
- tjholowaychuk 14y agoNothing wrong with backbone, but I do find it hilarious how it took a lib creating faux classes to get people to stop writing hideous code, you can write clean code with or without Backbone, and it'll look nearly identical. Cleanliness is not in a framework, it's in your head.
- glassx 14y agoI notice the same thing with Rails vs Sinatra. People complain that Sinatra is problematic because it doesn't enforce a directory structure, but you can still make clean, organized code with it.
- hasenj 14y agoBackbone.js is not going to solve your DOM spaghetti problems. You will still bind to events, you will still manipulate the DOM, you will still do all the manual work. I really recommend looking at Knockout.js instead. It really gets rid of all the DOM manipulation code that tends to become so complex and spaghetti like. How? It provides a declarative language for two-way binding between the UI and the data. Check out this example: http://jsfiddle.net/FEVbz/ http://jsfiddle.net/FEVbz/ In the HMTL pane, edit the input boxes and watch as the other DOM elements update automagically. Notice how simple and clean the Javascript code is. All it's doing is initialization and setup. Nothing else. No event binding. No dom manipulation. No spaghetti. No nothing. Shameless plug: Here's an article I wrote about why I think Knockout.js is so much better than Backbone.js http://dev.hasenj.org/post/35572197519 http://dev.hasenj.org/post/35572197519
- nerd_in_rage 14y agoI've taken a look at both Backbone and Knockout over the past week or so, and I definitely prefer the Knockout approach. Backbone... I just don't get it. It seems like there's too much complexity. I'm mainly a back-end developer, so perhaps it's just me.
- thibaut_barrere 14y agoLike you, I'm more a back-end developer and attempted to pick Backbone initially for my SaaS, but I wasn't very successful with it. Later I discovered Knockout and in 2 hours, I was up and running, and it never got in the way so far. I can only encourage people to at least try the tutorials, it will be time well spent: http://learn.knockoutjs.com/ http://learn.knockoutjs.com/
- rimantas 14y ago> It seems like there's too much complexity Backbone helps you to do the things you understand. Knockout let's you do things you don't necessarily understand. Sometimes black-box approach is OK. Sometimes not.
- 14y ago
- Kiro 14y agoI use jQuery a lot but Backbone is like Greek to me and so is every tutorial I've seen. I just don't get it and I fail to see the benefits. Can someone point me toward a good and simple explanation/tutorial?
- CWIZO 14y agoI feel exactly the same. I tried to make something simple with bacbone the other day but I just couldn't wrap my had around it. Maybe I'm just stupid, but I too would like to know if there is some article that would explain things more clearly.
- modarts 14y agoTry the Peepcode videos: https://peepcode.com/products/backbone-js https://peepcode.com/products/backbone-js
- uptown 14y agoI'm going through the same thing. I just got a small application up and running using Backbone.js yesterday, but it still feels like a more-complex application could get messy. I did have one question regarding redundancy - if I take advantage of something like validation with Backbone, I still need to do the same validation on the server-side for any data that I POST or PUT back to the server since I can't trust what comes from the client. Is the only gain from doing the client-side validation in Backbone the faster feedback to the user without requiring a round-trip to the server? I'm currently trying to decide between Backbone.js, Angular.js, Ember.js or sticking closer to what I know with a jquery pjax solution.
- mcgwiz 14y agoThe primary gain is faster feedback, but this can also reduce server load. In general, you should never trust user input, so you should validate on the server. (In particular, not only is it possible for users to manipulate/disable your client code, including validation logic, but it's trivial to hand-craft requests to your server.)
- 14y ago