Do you really want an SPA framework?
First, sell your soul to the framework maintainer…
What’s wrong with an SPA Framework?
I author and maintain quite a bit of software. Much of my code is available in commercial applications (SnapLogic, Qualaroo), OSS libraries on Github and NPM, or demonstration applications like Typebomb. I am the co-author of the book that Dr. Dobb’s Journal named as one of the best developer books of 2014 and called it the “Master Handbook” for SPAs. Yet despite numerous requests I have not published an SPA framework.
Before we proceed please note that everything has its place. SPA frameworks can be useful to new or casual developers who don’t know or care how an SPA works. But before you hitch your star to Ext, Angular, Ember, Aurelia, Meteor, Backbone, Knockout, Vue, or Mercury or dozens of others, please consider that every shiny new tool has its cost. Here are some precautions you might want to consider before you dive in.
Frameworks and the inversion of control
When we use an SPA framework, the quality and capabilities of our application are strongly limited by it. This inversion of control is a major impediment in building a a nimble, flexible, testable, and maintainable application that can stand the test of time.
When we use a sound architecture and libraries instead, however, we can swap libraries out when they are updated or better one becomes available. Or we can decide not to change a thing if an update doesn’t suit our needs. We can mix and match the best-for-our-purpose libraries instead of using a framework’s mishmash of solutions of varying quality. Why, for example, should one bother overriding the mediocre mechanisms of a framework when just removing the framework can results in simpler and easier to maintain code?
Does this mean we need to write everything from scratch?
Frameworks and complexity === insanely long cycle times
Well, actually, we do. If our overhead for producing working development code is greater than say, oh, 5 seconds, then somebody out there is definitely kicking our ass on cycle times. We can fail 300 times an hour with a 5 second cycle time. In other words, if it takes 200 failures before success, we will need a minimum of 40 minutes to resolve an issue. However, if our cycle time is 5 minutes because of the multi-compile overhead of an SPA framework, our minimum time before success will be 72 times longer, or over two full work-days. You make the call.
Long cycle times not only kill productivity, but they also stifle innovation because only so many solutions can be tried within any given period of time. To paraphrase Thomas Edison, the key to innovation is to learning how to fail really fast.
Frameworks DSLs aren’t portable
Been there, got the T-shirt, bombed the airport
I once used a framework (not my choice) and had to wait months for a new version to support a desired feature. Once the framework was updated, I discovered excruciating pain of trying to find and fix all the regressions. It wasn’t easy, of course, because (a) some of the most dastardly bugs were within the framework itself, and (b) frameworks tend to intermingle display and business logic, so testing was tedious and difficult. Which, of course, brings us to our next subject…
What about testing?
Testing a Single Page Framework Web Applications (SPFWA?) often requires an additional framework for testing the simplest of logic. Selenium, ZombieJS, and other intricate solutions are often employed to test the most basic model logic that shouldn’t require display testing at all. Yet there it is. Complexity breeds complexity.
When we use a sound architecture and libraries instead, however, we can easily decouple display and business logic so we can regression test our application in less than a second. My commit hook for the above application eventually ran the full regression suite and JSLint for all changed files in less than 4 seconds with over 600 assertions and ~95% coverage. We could refactor and reorganize the code at-will because only the most obscure bugs could sneak past the regression tests. The architecture and method of testing scales very well on larger projects too.
What are your preferred libraries
Please see hi_score for the most up-to-date list of libraries. Eventually this list will be moved there.
|DOM + Util||jQuery||A powerful, stable, tight library|
|AJAX||jQuery||… but prefer WebSockets, see below|
|Client Data||TaffyDB||A powerful and flexible SQL-like client data management tool|
|Coverage||Istanbul||The best JS code coverage tool I have found|
|DynamicCSS||PowerCSS||Insanely fast and efficient JS-CSS engine|
|Linting||JSLint||Avoid stupid mistakes with a commit hook|
|Events, promises||Global Events||Use the same event and promise methods for both logical and browser events|
|Routing||uriAnchor||A jQuery plugin for robust routing that includes support for dependent and independent query arguments|
|SVG||D3||Easy graphs and charts|
|SVG||Low-level jQuery plugin|
|Templates||Dust||Uses a powerful template DSL that minimizes the temptation to intermingle business and display logic|
|Testing||Nodeunit||Create a lightening fast regression test suite and use it as a commit hook|
|Touch||Unified events||Unified desktop and touch events|
|WebSockets||Socket io||The WebSockets protocol is faster and more flexible than AJAX for most applications. Consider using pure websockets client with a websocket server on a NodeJs with modern browsers (IE10+)|
But I want the comfort of a Framework
We can clone hi_score to get a great starter project. It includes all the tools needed to deploy a modern, well packaged SPA for production. On Linux (Ubuntu 16.10/16.04) first ensure we have to ensure system prerequesites are met, although a professional JS developer will typically have these already installed:
hi__score includes automatic download and linking of best-in-class libraries, code standards, architecture diagrams, example code, and code compression and obsfucation. It employs typecasting to minimize type errors. Check out the code coverage on coveralls, and watch this blog for future hi_score announcements.
A parting thought
Please see this article on Angular which echoes many of the issues discussed above. Perhaps it should have been called “Angular JS: the ColdFusion of the next-generation”??