📜 ⬆️ ⬇️

Javascript MVC Framework: Comparing Marionette and Chaplin



Developing JavaScript applications is a hot topic and people are interested in which framework to choose. In this article I will compare two of them.

Marionette and Chaplin are frameworks that run on top of the popular Backbone.js library. Both want to facilitate the development of one-page JS applications. In such applications, the frontend performs tasks that were performed on the server in the past (such as rendering HTML from data).
')
Backbon is designed as a minimalistic library, and not as a full-fledged framework. My experience has shown that Beckbon is only good as the core of JS application architecture. Both Puppet and Chaplin appeared because Beckbon provides little structuring for real-world applications. They solve the same problems. So there are quite a few similarities between them - perhaps even more than differences.



First of all I want to declare that I am co-author of Chaplin. But I also worked with the Puppet and follow its development. There is another ambitious framework based on Beckbon - Toraks. Since I did not work with him, I did not include it in this comparison.

Content



  1. Non-technical aspects
  2. General features that eliminate the disadvantages of Backbone
  3. Advantages of the Puppets
  4. Disadvantages of Puppets
  5. Advantages of Chaplin
  6. Disadvantages of Chaplin
  7. Conclusion


Non-technical aspects



I’ll talk about technical details later, but let's face it - the decision to choose a program is strongly influenced by their marketing, reputation, success stories and documentation.

Puppet and Chaplin are open source projects released under the MIT license and actively developed on GitHub. Their authors participated in the development of several large Backbon applications and transferred their experience of creating good architecture so that you would not have to step on the same rake.

Well known companies use Puppet and Chaplin. It is difficult to say for sure, but in general the number of users is about the same. The Puppets Ecosystem is bigger, so many people use only parts of the Puppets instead of the whole.

Chaplin was more popular in the beginning, and the Puppet became famous later. The puppet is friendlier to beginners and is well documented, which is probably one of the reasons why she is chosen. Another reason for the popularity is the contribution of Darius Bailey, the creator of Marionette, who wrote a bunch of articles on the development of Beckbon appliqués. He also speaks at conferences and records video lessons .

General features that eliminate the disadvantages of Backbone





Event-oriented architecture without the mess



A key feature of Backbone is the division of responsibility between views and models. They interact through events ( Publish / Subscribe ). Using Backbone.Events , you can make an event-oriented architecture . This is a good way to separate parts of your application from each other.

Both Puppet and Chaplin define application bottlenecks on Beckbon. Cleaning event listeners is critical in an event-oriented architecture. The life cycle is important: the component that created the other component is responsible for removing it. Puppet and Chaplin solve these problems in different ways. They not only promote the use of Publish / Subscribe, but also provide tools to avoid the common mistakes associated with the approach.

Structuring the application



Models and views are low-level patterns. On top of this, Beckbon provides only Routers . This is a very thin layer and is probably the most problematic part of the backbone. With a pure Beckbon router, you cannot create a normal high-level architecture with memory management. Both Puppet and Chaplin introduce controllers .

Powerful view conventions



Following the simplicity of Beckbon, his views and their rendering is an abstract thing. The backbone view is responsible for one DOM element, but Beckbon does not provide tools from the box to drive data into the element and insert it into the page - the View#render method is empty by default.

Puppet and Chaplin provide view classes with a robust rendering engine (see Marionette.ItemView and Chaplin.View ). On top of this, you need to choose some template language, such as Mustache / Hogan , Handlebars or HAML-coffee .

Both libraries have agreements on when to render views and how to insert them into the DOM. You can transform the model data before it is sent to the template. This is useful, for example, for computed properties.

Views are probably the most difficult part of your application, so Puppet and Chaplin are additionally provided with helpers. With them, you can create nested views and declare named regions . You can also declaratively register model events (easier and more readable than this.listenTo(this.model, ...); ).

Pure Backbon is also a minus view for working with collections (see Marionette.CompositeView and Chaplin.CollectionView ). The bottom line is this: use a separate view for each collection model. With this complex lists can be implemented through simple and structured code. The views for collections are smart in themselves, they will not regenerate the entire list because of one model.

Advantages of the Puppets





The puppet is a storehouse of useful patterns. It is modular, you are not required to use all parts of the Marionette. You can start with several parts and start the rest later. Some of the features of the Puppets come from individual plugins for Backbone, for example, Backbone.BabySitter and Backbone.Wreqr .

In the Puppet there are also cool unique features. In my opinion, the most powerful are application modules and smart view management .

Modules



Application modules are independent parts of the architecture, which may consist of routers, controllers, models, and views. The modules can be started and stopped, you can still define “hooks” that will be executed before the stop. They can also be lazily loaded when the route matches the one set in the module.

BBCloneMail is an example of an application that consists of two modules ( mail and contacts ). In this example, only one module is active at a time. But in general, modules may not “replace” each other. The modules have their own routers, which must be started from the very beginning ( contact router, mail router ).

Modules can be nested. Your main application, Marionette.Application is also a module. Technically, there are some differences between Marionette.Application and Marionette.Module, but I hope that in the future they will become more uniform.

You most likely will not need to use several modules from the very beginning, but this is a good feature that helps to divide the application into small, related units.

View Management



Another powerful part of the Puppets is smart view management. Views can be easily nested with each other using the BabySitter . In addition, Puppet adds several abstractions, like Layouts and Regions. Layout is a view that contains named regions. Region is the object that is responsible for the DOM element. Examples of regions are header, navigation, main, sidebar and footer.

Where do you need to render views and insert them into the DOM? In the regions! Instead of managing DOM elements directly, you can define a Region once and then just write mainRegion.show(view) , for example. This will render the view and append it to the DOM element corresponding to the region. A region holds only one view at a time, so the old view is “closed” (removed from the DOM and safely released from memory).

With nested regions, you can build a complex interface simply through readable and supported code.

Disadvantages of Puppets



For the sake of brevity, I described a couple of unique Marionette features.

I do not like weak abstractions and vague recommendations for effective use.

Routing and controllers



For example, Puppet provides very few add-ons on top of Backbone.Router. In my opinion, this is important, since the Beckbon router does not provide any agreements on clearing the created objects from memory when the next route becomes active. In principle, you can implement centralized cleaning using route events, but this is a crutch.

There are modules in the Puppet that can be stopped and regions that can be closed . But each time to start and stop modules or close regions is clearly not comme il faut.

Marionette.AppRouter - step in the right direction. His idea is to separate the configuration of the route from the code. When the routes match, AppRouter refers to the Controller instance that responds to it.

The controllers in the Puppet have no definite purpose, they only “control” something. They can subscribe to events through Backbone.Events Events, they have methods initialize and close . This is definitely useful, but you need to think for yourself how to use them and when. Usually, models and views are created there.

Global and private objects



In the Puppet, modules and classes sit in a global variable, for example, window.BBCloneMail.MailApp.Controller . With a puppet, it becomes tempting to create globally accessible instances of classes, although it’s not at all cool to do so. In the BBCloneMail example, some objects are passed and returned from functions, while others are available globally (for example, BBCloneMail.MailApp.controller ).

When you read the code, it is not obvious which objects are globally accessible and which are globally used. With the Puppet, I advise you to use the object-capability pattern, with which you can associate objects without global namespaces.

Default Templates



By default, views read their templates from the DOM and compile them with the Anderskor template language ( _.template ). It's simple, but embedding templates in HTML is not recommended (for example, with Chrome Web Store guidelines — applications with templates that are compiled on the fly simply won't go there). In the end, the templates must be in separate files, precompiled. But, of course, you can easily add this to the Puppet - just work with Renderer .

Advantages of Chaplin





In comparison with the Puppet, Chaplin looks more like a framework. He is more stubborn and has stronger agreements in different areas. He took the ideas of server-based MVC frameworks like Ruby on Rails, which follow the convention over configuration principle. Chaplin's goal is to provide proven practices and a convenient development environment.

Coffeefree and OOP



Chaplin is written in CoffeeScript , a meta-language that compiles into JavaScript. However, applications on Chaplin may not use coffee, because Chaplin is just another JS library.

The use of a cofescript is part of the Chaplin idea that development should be simple. Coffeefree imposes Douglas Crockford's guideline from the book “JavaScript - The Good Parts”. As a puppet, Chaplin promotes the use of ECMAScript 5 Strict Mode .

With coferscript, defining and inheriting classes is easier and cleaner than through Backbone.extend .

Chaplin also actively promotes the redefinition of methods in child classes and the use of the super cofescript (or its equivalent in JavaScript) and tries to make class inheritance work clearly. For example, if you declaratively define events for a class and its successor (via View#events ), both of them will be applied.

Modularity via AMD or CommonJS



Chaplin demands to use modules - CommonJS or AMD will do . Each module must define its own dependencies and export something (a constructor function or a single object). Usually in Chaplin, there is one class and one module per file.

It's not easy to use AMD , you need to know loaders a la require.js and optimizers like r.js. Alternatively, you can use CommonJS modules and the Brunch collector, everything is much simpler.

The puppet also supports AMD , but does not force them to be used.

Fixed application structure



Chaplin gives a fixed structure. It handles the bulk of all actions.



In Chaplin, there is a central place to define all the routes. Route indicates controller action. For example, the cars/:id link template points to cars#show , that is, to the action (method) of the CarsController controller CarsController .

The controller is the place where the models and views are initialized (for the main part of the screen, not the sidebars, headers). In general, the controller action usually responds to one screen of your application.

Memory management





The main idea of ​​Chaplin is the controllers cleared from memory. The main rule - the current controller and all its properties (models, collections, views) are deleted on the next controller. Even if the route indicates a different action of the same controller, the old controller instance is deleted and a new one is created.

Removing previous objects when the next route matches is a simple and effective way to clean up links. But some objects would be better to keep in memory for several or all actions. For this purpose, there is Chaplin.Composer , which allows you to share models and views. If the stored object is not used by the next route, it is automatically cleared.

In Chaplin's applications, each object is easily cleaned. All Chaplin classes have a dispose method that will render the object unusable, remove all links and freeze it.

Hidden instances of classes and Publish / Subscribe



A well-known JavaScript programming rule is to avoid global variables, and Chaplin tries to force them not to use them. Classes in Chaplin are CommonJS / AMD modules that are not available in global namespace. All copies, in turn, are hidden. Two instances should not be linked to each other, unless they are closely related, like a view and its model.

Objects can communicate with each other in an unbound form using the Publish / Subscribe pattern. For this purpose, there is Chaplin.Mediator . The mediator can also be used to store some frequently used items, such as the current user's model file. After creating the necessary properties, the mediator is sealed in order not to become a global garbage dump for your application.

Wise management



Chaplin is also strong at managing views . It has named regions and nested views. Chaplin uses a different approach to rendering views and inserting them into the DOM. The viewers may have an autoRender flag and the container option. If they are, views will be rendered immediately after creation and inserted into the DOM automatically. Instead of the container option, you can specify a region , so that instead of a direct link to the DOM element, attach a view to a previously registered region.

In addition to global regions, there are no abstractions in Chaplin. Marionette.Layout and Marionette.Region type puppets. In an application with a Puppet, there are usually several nested regions and layouts. In the application with Chaplin, you will have fewer main regions and more views embedded in them. Of course, you can still create views for reuse with the behavior of Marionette.Layout , for example, ThreePaneView .

Disadvantages of Chaplin



As a co-author of Chaplin, I can be biased. But I also see weaknesses and potential for improvement. Obviously, the Puppet has found more suitable solutions to some problems.

As I have already noted, Chaplin delineates the life cycle of each component and is therefore strong in memory management. What is one of the main problems when creating web applications on Beckbon. Chaplin found a solution that works well, but it is not perfect and controversial . This feature has evolved and must develop further.

Beginners difficult to understand the whole picture of Chaplin at once. Memory management, modularity, and other Chaplin concepts are new to many JavaScript developers. At the same time, if at the beginning these features seem to be “in the grip”, the application will benefit from them in the long term.

Publish / Subscribe is not a unique Chaplin opportunity when compared to the app vent Puppet. In fact, app vent is more flexible, as each module comes with its own event aggregator.

Chaplin uses Pub / Sub not only for broadcasting events, but also for launching commands that there is an abuse of the pubs. Backbone.Wreqr implements the Command / Request / Response pattern for this case. Chaplin should take this opportunity from the Marionette.

Conclusion



The puppet is more modular, you can only use parts that you like (I think you should use most of them, since they can improve the application). Instead of a single central structure, you can create a composite architecture with independent modules. This provides a greater separation of components, but you must understand how to use them properly.

Chaplin is more like a framework, it is centralized and strict. The authors of Chaplin believe that agreements increase convenience and productivity. But, of course, your opinion on this matter may be different.

Because of his goals, Chaplin covers more problems than other libraries. For example, there are rich routing and dispatching systems that replace Backbone.Router, but use Backbone.History.

In comparison with the Puppet, Chaplin is monolithic. This does not mean that you can not do things differently. You can still customize, modify or change the base classes and break all the rules.

Standing on the shoulders of giants



So which library to choose? I do not think that the choice is clear. Obviously, you should build architecture on the library that best suits your needs. But you also need to understand and learn how to apply its best practices.

Using Beckbon, you need to develop a scalable application architecture yourself. Do not write applications on pure Backbone , stepping on the same rake as others, learn from their experience. Take a walk through Puppet, Toraks, Aura , Chaplin and other architectures to explore them.

To start using Chaplin, I recommend using one of our basic boilerplates: CoffeeScript boilerplate with support for Handlebars templates, or its equivalent in pure JavaScript . They include some conventions that we find quite useful: the folder structure and file naming conventions, the style of writing code, the template engines.

If you are looking for a mature development environment for a quick start, try
Brunch with Chaplin or Chaplin + Rails boilerplate .

For a more practical introduction to the Puppet, read the article on Smashing Magazine ( first , second parts). There are a whole bunch of articles, video tutorials and presentations on the Puppets wiki .

Thanks



Thanks to Darick Bailey, Sebastian Deutsch, Paul Miller and Paul Wittmann for reviewing this article and contributing to the development of Puppet and Chaplin.

Source: https://habr.com/ru/post/177843/


All Articles