Log(n) Engineering

Component-driven Web Apps

An overview of today’s Web App implementations and how we can improve the development process by using a component-driven approach.

Also, how are some of the popular libraries and frameworks (Angular, React, Polymer) approaching componentization.

Topics

  • Overview of today’s Web Apps
  • What has changed?
  • Conclusion

Overview of today’s Web Apps

There are many approaches to implement web applications, but for this post’s purposes we will only focus in one of the most common approaches:

The SPA (Single Page Application) consuming data from a REST API. Also known as Client-side rendered apps.

So, how do we currently implement SPAs?

“…separating the data from the presentation of data by having a model layer that handles data and a view layer that reads from the models.”

– Mixu’s single page app book

Does this sound familiar? Yes, you’re right that’s MV*.

There are many good libraries and frameworks available that help us implement SPAs such as Angular, Backbone, Aurelia, among others. We will not enter into any of those libraries' details just because we want to stay focused in the general architecture of an application.

This is how an SPA looks like nowadays:

SPA-architecture

Things may look different depending on the library we choose to implement our SPA, for example if we use Angular we would probably have a Service reading from and writing to our data storage and a Controller syncing up our templates with our data state, but at the end of the day it all comes back to the above architecture (just with different names).

Now, lets take a deeper look at how we actually write our application’s code (HTML code to be more specific). We will continue using Angular for this example:

1
2
3
4
5
<section ng-controller="productList">
  <ul>
      <li ng-repeat="prod in products">{{ prod.name }}</li>
  </ul>
</section>

Despite the fact that HTML5 introduced a lot of new semantic elements (such as <header>, <main>, <footer>), our HTML code still falls short of describing our application semantics. Consider the above example, wouldn’t it be nice to just have a <productList list="products"> component?

You can go and see this by your self, just open your browser developer tools and take a peek at the HTML code of any site, you would probably see a lot of HTML tags thrown together without any context.

Cool, we just identified the problem, now lets see what is changing in order to fix it.

So, what has changed?

A lot is changing in the web-tooling world, some interesting things that happened recently are:

  • ES2015 spec was approved: I’m really exited about this; a lot of cool things were included in this new specification: arrow functions, default parameters, let scoping, rest parameters, spread operator, all these features will make JavaScript programing even more fun. We will also have access to features like generator functions and modules that will help us structure our code in a more proper way.

  • Polymer 1.0 production ready: The Web Components specification is awesome if you haven’t played with this yet then here is a little introduction so you can start. This specification includes the following set of technologies:

    • Custom Elements, that enables to define and use new types of DOM elements.
    • HTML imports, a way to include and reuse HTML documents in other HTML documents.
    • Templates, used to declare fragments of HTML that can be cloned and inserted in the document using JavaScript.
    • And finally Shadow DOM, a method of combining multiple DOM trees into one hierarchy.


    Unfortunately, Web Components are not fully implemented in all browsers yet, but, thanks to the Polymer library, we can use all these features in modern browsers today.

  • Angular 2.0 has an estimated release date of the end of 2015: Angular 2.0 will target ES2015, and will introduce Component Directives; these will allow creating reusable components by encapsulating JavaScript logic, HTML and an optional CSS style sheet. As you may already have guessed, this type of directives makes use of the Web Components spec to accomplish this encapsulation.

  • React added ES2015 support: React’s component philosophy combined with ES2015 features like modules and classes results in a really powerful development tool.

All this movement has made possible (among other things) to have better componentization on the web.

In fact, Angular, Polymer and React have something in common; they are all adopting a component-driven development philosophy. So, I think is ok to think that components are the future of web application development.

Lets talk about Component-driven development.

The term is not new at all; we as developers deal with components all the time, Node modules, jQuery plugins, JS libraries and even entire systems can be components of bigger systems.

However, this is not the type of components we want to talk about; we will talk about components as an abstraction of a UI section in our application; where this section represent a concrete entity or functionality. Let me illustrate this with an example:

Consider the input element.

1
<input type="text" id="first_name">

We can say that the input element is a UI component that encapsulates it’s own styles, structure and functionality, and it can interact with other components if necessary (like the label component).

Also, the input component could be part of a bigger component; the form component.

1
2
3
4
5
6
7
8
9
10
<form>
  <fieldset>
      <label for="first_name">First Name:</label>
      <input type="text" id="first_name">
  </fieldset>
  <fieldset>
      <label for="last_name">Last Name:</label>
      <input type="text" id="last_name">
  </fieldset>
</form>

This componentization makes development a more descriptive and declarative process. It just feels natural to throw components together in order to create new functionality.

In component-driven development you can create your own custom components and then use those components to create even more sophisticated components. For instance, lets say you are building a travel application; you would probably want to have a <searchbox> component and a <resultlist> component. The cool thing is that these components (if they are well implemented) are reusable and you can use them in others parts of your application, or even in a completely different application.

Now our HTML code will clearly describe our application logic and apart from that our code is now more flexible, scalable, reusable and testable.

http://i.giphy.com/aurUBBayxC55m.gif

That being said, lets see how we can implement components in different popular libraries and frameworks:

Angular

1
2
3
4
5
6
7
8
9
import {Component, View, bootstrap} from 'angular2/angular2';
@Component({
  selector: 'my-component'
})
@View({
  template: '<h1>My first Angular 2 component</h1>'
})
class MyComponent {}
bootstrap(MyComponent);
1
<my-component></my-component>

React

1
2
3
4
5
6
7
var MyComponent = React.createClass({
  render: function() {
    return (
      <h1>My first React component</h1>
    );
  }
});
1
<MyComponent/>

Polymer

1
2
3
4
5
6
7
8
9
10
11
<dom-module id="my-component">
  <link rel="import" type="css" href="my-component.css">
  <template>
    <h1>My first Polymer component</h1>
  </template>
  <script>
    Polymer({
      is: 'my-component'
    });
  </script>
</dom-module>
1
<my-component></my-component>

If you want to give this a try, you can use any of the following tools:

  • Babel and Traceur will let you write your code in ES2015 and transpile it to ES5 later to make it work with every modern browser. You can also use React + Babel because Babel supports JSX out of the box.
  • Polymer will let you play with Web Components.
  • Regarding Angular well, we will need to wait for version 2. However, you can also use current directives implementation to create components without any problem.

You can also find a real life example on this repository:

https://github.com/dfernandeza/clock-component

Conclusion

Web applications have become a lot more complex and as a response for that, the web community came up with all this awesome technologies that try to make our life easier. Component-driven development has pretty good advantages that not only makes our job easier but also helps us deliver better quality, some of these advantages are:

  • Reusability: having encapsulated components makes it easier to reuse code across the application.

  • Maintainability: it should be easy to find a specific piece of functionality if the implementation details are encapsulated within components. Also, adding changes to one component should not introduce bugs in other components.

  • Testability: It should be easy to test that each component works properly on its own, and also how those components interact with each other.

  • Smart view re-rendering: if the data presented on a UI section changes we want only that specific section to be re-rendered.

That’s it, now you have a little more understanding on how your favorite library or framework approaches componentization.

Hopefully this post was useful and you may now consider component-driven development for your next web app.

Recommended links

Component Interop With React And Custom Elements

What’s New in AngularJS 2.0

Angular 2 Series: Components

Eric Bidelman - Google I/O 2014 - Polymer and Web Components change everything you know about Web development