Post on 16-Jul-2015
Backbone/MarionetteExperience recap in scope of @SoftServeInc projects involvement
Andrii Lundiak @landike2015
Agenda
• Project’s Technology stack
• SCM project review
• DMG project review
• EWQ project review
Project’s Technology stack
• SCM [2013]:
• [40%] Backbone.JS 1.0.0 + [60%] Marionette.JS
• + Backbone plugins (localStorage, stickit, wreqr, babysitter, syphon, validation), Underscore.JS 1.5.1, Require.JS 2.1.8, jQuery 2.x and plugins(cookie, validate, jasmine-mixture), Bootstrap 2.3.2, Node.JS + Grunt.JS, Jasmine.JS, LESS, i18next.
• DMG [2014]:
• [70%] Backbone.JS 1.0.0 + [30%] feature development,
• + Underscore.JS, jQuery 1.x, jQueryQueryBuilder, Select2.JS, Bootstrap 2.x, Node.JS + Grunt.JS, LESS.
• EWQ [2014]:
• [80%] Backbone.JS 1.0.0 + [20%] Marionette.JS 1.8.x,
• + Underscore.JS, jsRender, jQuery 2.x, Bootstrap 2.x, Node.JS + Grunt.JS.
SCM
• UI part: First what we
implemented was List based on
client UI/UX team rework of
Bootstrap 2.x.
• Backbone part: Based on
backbone plugins (.localStorage,
router), jquery.cookie and auth
token from backnend we
implemented session.JS, and
used over the application.
• Marionette part: Then we
implemented many instances of
Marionette ItemView,
CollectionView, CompositView,
Region, Layout, Routes,
Controllers to manage all
features by Marionette.JS.
SCM: backbone part
• SessionModel = Backbone.Model.extend({ … })
• BaseRouter = Backbone.Router.extend({ … }) then
• Router = BaseRouter.extend({ … }) depends on Session and controllers
SCM: marionette part
• App = new Marionette.Application({ … }) depends on Session and Router.
• We added Regions in MainLayout,
then we created MainController,
depends on MainLayout and
a few other controlers.
SCM: marionette part #2
• We created feature instances as views and
subviews using Marionette.ItemView(),
Marionette.CollectionView(),
Marionette.CompositeView()
• We created a few regions and layout
(including nested) via Marionette.Layout()
but didn’t use directly Marionette.Region and
marionette.RegionManager.
• We didn’t use Marionette.Controller directly.
• We didn’t use Marionette.Module.
DMG
• Existed codebase was on top of Backbone 1.0, and we couldn’t migrate to newest version. So we
extended codebase as much as possible.
DMG: Improvements
• We separate small features into modules/widgets, but modules were NOT
native Backbone code. We wanted to implement it as marionette modules, but Client
declined Marionette.JS usage.
• But we already have known marionette approaches, so we kinda borrowed it, and
reused in codebase.
• Client has old view (BaseView), which was built on top of backbone 0.x version. So
after code research, we simplified view to simple usage Backbone.View().
• There were many not needed dependencies, so we simplified this also.
EWQ
• One of major improvement in EWQ comparing DMG –Widgets flexibility.
EWQ: “Loaders/Builders”
• There were a few entities: plugins, widgets, admin modules,
dashboard modules. And all are quite the same from JavaScript
pov. So we created core.js with loaders, so that their behavior
looks the same, but result different.
EWQ: Worklist #2
• In fact, we reworked worklist from previous project, because client was the same. But this time we used Marionette.JS, due to “proof-of-concept” phase. Marionette [.ItemView(), .CollectionView(), .CompositeView()] were successfully used again.
• Every module has own router, based on Marionette.AppRouter(), so that we dedicated feature has ~100% independence and behave like Lego component.
• Every module has controller implemented with Marionette.Controller()
EWQ: modules
• We added many modules, so that
every feature would be separate
independent module.
• In fact we used 2 ways how to
create modules: native Backbone
and Marionette.Module() [but only
one experimental modue]
• For sure, potential way to use
ONLY Marionette.Module().
Otherwise, you have to implement
namespaces (as our client did in
fact before us).
Outcomes
• It’s better to not freeze with old version of 3rd party library. As result migration/extend/override/inheritance might be very complex and painful.
• Better to follow MV* structure, especially where it’s very needed. Grouping file by system “Feature contains” set of models, collections, views, templates, controllers, etc. is really good and independent system.
• Implement code as modularized as possible. Marionette.Module() helps here very much, and we got rid of namespaces.
• Better to separate controlling logic using Marionette.Controller()
• Complex lists, sortable tables, scrollable lists are very good implemented with Marionette.*Views().
• UI layout, page containers, separate UI features are very good implemented and scalable by using Marionette.Layout() and regions.
• In any case, it’s very useful to have global Events bus (Backbone.Wreqr.EventAggregator aka App.vent)
Resources to read
• http://backbonejs.org/, http://underscorejs.org/,
• http://backplug.io/, http://marionettejs.com/
• https://github.com/marionettejs/backbone.marionette/releases
• http://lostechies.com/ - awesome site, very detailed, many examples.
• http://samples.leanpub.com/marionette-gentle-introduction-sample.pdf
• http://ricostacruz.com/backbone-patterns/
• http://blog.shinetech.com/2013/11/26/backbone-antipatterns/
• http://worknme.wordpress.com/2014/08/18/backbone-marionette-short-review-1/
• http://habrahabr.ru/post/207730/ [RU] – Backbone => Marionette
• http://habrahabr.ru/post/177843/ [RU]- Marionette vs. Chaplin.
Resources to try
• https://github.com/theironcook/Backbone.ModelBinder
• https://github.com/NYTimes/backbone.stickit
• https://github.com/marionettejs/backbone.wreqr
• https://github.com/marionettejs/backbone.babysitter
• https://github.com/powmedia/backbone-forms
• https://github.com/malroc/backbone-component
• http://perka.github.io/backbone-ui/
• http://loicfrering.github.io/backbone.datagrid
• https://github.com/nilbus/Backbone.dualStorage
Special Thanks to
• Vasyl Tsarevych, Vitaliy Petrychuk, Dmytro Gorogotskyj, Ievgenii Neiman,
Sviatoslav Novosiadlyj, Ivan Matiishyn, Yuriy Lytvynenko, Dmytro
Yermolayev, Yevgen Motrych, Yuriy Kapechuk.
• All these guys were in my team(s). By working with them I had great
leadership relations with them, and besides I’ve got huge amount of
experience.