Building simplicidade.org: notes, projects, and occasional rants

Web Application Architecture

My focus is not as a JavaScript developer, so I don’t track the ecosystem closely. At the same time, I do need to write and maintain Web applications. The following architecture and tools are the current best-of-breed for me.

TL;DR version - I picked these tools:

  • React + JSX for views;
  • Backbone for model;
  • Redux for glue;
  • react-router plus react-router-redux for routing;
  • npm for dependencies;
  • webpack for packaging and bundling;
  • node for application server.

I specifically do not use Gulp, Grunt or any of the make-wannabies. Most of the time, npm run is enough.

Please note that this covers the front end applications only.


Some of the objectives used to choose these tools:

  • avoid big frameworks: they have value, but also a big learning curve. I’ve managed a large Angular project before (version 1.4, about 800K of compressed app code), and it has some benefits, but I rather have smaller pieces that I can learn enough to be productive in a day;
  • one bundle, multiple files: the extremes of app delivery - a single large bundle or multiple small files. With HTTP/2, the second is more useful, but as all extremes, I believe there is value in the middle ground. I prefer to have one file per logical section of the app, plus other bundles with code that changes less often;
  • message passing-based inter-component communication: my brain is hard-wired to thing in terms of distributed isolated components that talk to each other based on messages, so I look for that in the tools I want to work with. It just easier this way to add another component, listen to the messages you need, and generate the messages or actions you want, without having to make any or big changes to already existing components;
  • immutability: I prefer never to update state, always create state from scratch, based on current state plus actions. It’s not that I’m a purist functional programming person, I rarely ever used pure functional programming languages, but it just makes sense to me, specially because of the for-free audit log, with all the advantages this brings, and the compose-ability and extension support it provides.

A good write-up with very similar ideas, and goals as mine is this: Welcome to Future of Web Application Delivery. I would not call it the “future” though, just “best current practice”.

Background information

Some interesting or important articles to be aware of:

Presentations I enjoyed:

And the obligatory React “awesome” resource page.

Application server

The application server is Node. For me, having the same language on the application server and the client-side makes a lot of things easier. I can easily swap components between server-side and client-side, and I can even use the same logic to render some parts of the app server side, for better SEO, or initial page render. To learn more, look for “react isomorphic”.

I use npm to manage my dependencies. I avoid Bower as their installs are usually very browser-oriented, and if I might need to move stuff from client-to-server, I rather have a single module for both. Not always possible, mind you, but usually ok.

I try to avoid Babel as much as I can. Although I see value in it, I rather stick to what ES2015/ES2016 Node supports natively. It is one less tool to learn. But although ES2015 is coming along on the browser side, it still lacks a lot of stuff, so you’ll still need it for client-side stuff.

Packaging and bundling

Webpack is awesome. Seriously, forget all others… You should start by reading the code splitting and the long-term caching sections of the documentation, if that doesn’t convince you of how awesome Webpack is, I don’t know what is wrong with you…

It is worth to keep track of RollupJS. It seems to produce much smaller bundles than Webpack (but see rollup#552, it still has some problems, in particular with RXjs). We can use rollup-loader to keep your Webpack workflow, though.

See this as a starting point for your Webpack experience: Helpers/presets for setting up webpack with hotloading react and ES6(2015) using Babel.

Related articles worth your time:

The View

Views can no longer be just simple templates. They require small amounts of logic, and there was always a big discussion where that logic should go in a pure MVC pattern.

I rather like “fat” views. I also don’t like to have the code and HTML of the fat views in separate files, having to jump from one to the other all the time. I rather like writing the views in the same language as the rest of the code, with small helpers to make generating HTML simple.

This is why the choice at this moment is React plus JSX. The productivity of having a single file with a component with both the code logic and HTML parts is unbeatable.

There is always the risk of getting a big mess with code and HTML in the same place. There were some dark places in my past with PHP, and HTML::Mason. But as with all tools, you can make use of them “In The Right Way”™, clearly separating business logic, and view logic in different places. Just because the tool allows you to mix HTML and code, you don’t have to make a mess of things.

For a quick explanation on views evolution until React+JS, see the Let’s talk about Views section of a presentation I liked. It makes the point very clearly.

Some Reference links:

On Isomorphic applications:

Presentations and videos that I liked:

  • Going big with React: video, 30mins. Very good one, shows difference between flow in a more traditional MVC app and a React app. Some of the diagrams help a lot to understand the flow of events.

The Model

This is one part where I’m not sure yet.

For now I’m using BackboneJS’s Backbone.Model. I like the Backbone.Sync API…

One thing that is still to be decided is how to talk to servers. One of isomorphic-fetch or SuperAgent will end up as the preferred way. I really like SuperAgent API but I’m not sure if I’m not going to find it too verbose in the future.

The Glue

You need to connect all the view components and the models that provide the information you need. Flux is the application architecture that Facebook developed for their own apps to connect React views with their Models.

I picked Redux as a simple evolution of the Flux architecture.

Redux has a great Getting Started with Redux tutorial, check it out.

The Router

For your routing needs, I like the model that react-router uses. It is simple enough but also clean and powerful.

Given the use of Redux, I prefer to use the react-router-redux wrapper, it makes my life easier.

Other tools

Starter kits, oh so many to choose from. I’ve still to pick one, these are the ones I’m looking at:

There is another school of thought that prefers no big start kits, that will allow you to grow more organically and learn the steps that most starter kits hide from you:

Examples

Alternatives

I’ve looked at some other systems while picking this set of tools. These are the ones I would consider as viable:

  • AngularJS: the Java-esq (aka. Enterprise Solution with the appropriate big set of terminology and standards) version of a Web application framework. You’ll find it very complete, decent performance, and it will have a suggestion (most of them strongly worded) for all your needs;
  • BackboneJS: I really like the Model and Router components, but I don’t like the View part. Still, a very useful tool.