Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Sunday, February 28, 2016

Building an application with a JavaScript-only stack

As I often do when checking out a new platform or language, I have been building a new pure JavaScript implementation of the Game of Life simulation like I did for Java 8.
In this case, my choice fell unto the MEAN stack:
  • MongoDB: a general purpose document-oriented (and as such NoSQL) database with support for querying and aggregation.
  • Node.js: the famous server-side JavaScript interpreter.
  • Express: a framework for providing REST APIs and web pages on top of Node.js.
  • AngularJS: one of the popular client-side JavaScript frameworks for building Single Page Applications.
The experience has been quite interesting, as you really get to know a language and its libraries when using it for a project; in a way that no book can force you to do.

Myths

Here are a series of myths I want to dispel after diving into a full stack JavaScript project for a few weeks.
It is true that there is less of a context switch when changing between the server-side and the client-side applications, since you are always writing the same language. However, this seamless transition is limited by several differences:
  • different language support: ECMAScript 6 has to be compiled down by tools like Babel to ECMAScript 5 to be compatible with any browser and Node.js version. Polyfills may be needed to try and unify the experience.
  • Different libraries: testing frameworks change between server and client, and so does how you build mocks.
  • Different frameworks: Angular and Express both have their own ways to express controllers and views.
  • Different tools: you install packages for the server-side with Npm but use Bower instead on the client.
The key about productivity is in being opinionated and choose (or have someone choose for you) a single tool for each purpose, without being carried away by the latest fashion. In this case I followed some default choices and trimmed that down to get:
  • Mocha and expect(), one of the three flavors of the Chai assertion library, for the server-side.
  • Npm and Bower for server-side and client-side.
  • wiredep to generate script and CSS tags for the single page to be loaded.
  • Grunt as a build and automation tool, wrapping everything else.
One sany way to pick up default and platform idioms is to start from a predefined stack, and you can do so by cloning a template or a generator like Yeoman. If the generator is well-factored, it will give you sane defaults to fill in the gaps such as JsHint and a configuration for it.
Another myth I would like to dispel is callback hell: if you use the ECMAScript 6 construct yield, you can pretty much write synchronously looking code by building an iterator of steps (each step producing a promise whose resolution will be passed in as an input for the next.) There's probably something even more advanced I didn't reach yet in ECMAScript 7. Don't take this as me saying you can write synchronous code in JavaScript (it only looks synchronous), and you definitely have to learn to use well the underlying layers of callbacks and promises before you can grasp what yield is really doing.

Productivity

With a reference to my previous experience in Java, the productivity of the JavaScript stack feels very good in the short term (I only explored that time frame), due to its simple syntax and structures, especially with support for ES6 which removes a lot of boilerplate.
For example, there is no need for Set<Cell> aliveCells = new HashSet<Cell>(); definitions like in Java, as you would write aliveCells = new Set() with purely dynamic typing (suffering the occasional unfortunate consequences of this choice, of course.)
To evaluate productivity and robustness in the long term you would have to build a much larger project, inside a team composed of multiple people.
I found the tight feedback loop of grunt serve was another positive impact on productivity: you can set up a watch on files so that every time you save the Node.js server is restarted, and the current browser page is reloaded. This is accomplished by LiveReload monitoring from the browser side with a WebSocket. Of course once you get the hang of the testing frameworks and their assertions, you're back to the even stricter feedback loop of running tests and have their output in milliseconds.

Conclusions

I'd say you can reach a good productivity in a pure JavaScript environment, even if I am unsure about the pure dynamic typing approach.
You'll have to get opinionated and choose wisely; to not introduce duplicates and clearly assign responsibility to each of this tool so that it's unambiguous that npm should not be used for client-side modules; to take control of your stack, as everything that you install is still only JavaScript code, copied into your project and that you can read to get a feel of what it's doing.
In programming, a feature that seems to consist of just a few lines of code often turns into an engineering project. In very dynamic and immature stacks such as JavaScript, it's even more important to build strong foundations, tools and processes to turn a blob of code into well-factored software.

Friday, November 27, 2009

The best things in life are degradable

When we talk about degradability, usually the discussion is about javascript widgets.
Degradability is the property of a web application to maintain much of his functionality even if javascript and other advanced tecnologies are disabled by the client. There are different approaches for crafting a degradable application: some developers choose degradable widgets which transform in normal form elements if javascript is not available (actually, they remain normal form elements), while Gmail has a different and separate plain old html version.
It is really possible that javascript is not used on the client: without taking into account screen readers and strange corporate browser policies, there are very important web users that normally cannot execute javascript and Flash. They are Google crawlers.
Thus web applications degradability is a good idea: enhancing the experience for some users, but still maintain a basic standard interface and functionality.
However, degradability is not limited to javascript libraries.

PubSubHubbub is the ugly name of a protocol for nearly-instant distributed dispatching of feed updates. A PubSubHubbub server for example can sit between blogs and readers: everytime the blog has published a new article, it notifies the server which takes care of informing subscribers, reducing the load on the blog hosting.
The system is degradable in the sense that even if the blog does not implement the protocol and does not notify the PubSubHubbub server when new content is available, the server will still periodically ping the blog at regular intervals to check by itself. The subscribers will get updates more slowly, but the overall functionality is preserved.

Finally, the most diffused implementation of a degradable device is in form of cache, which is a storage area included at the hardware level in every modern computer, and at the software level in nearly every site we visit.
The hardware cache, for example, is a very fast and small piece of memory that contains a subset of the computer Ram's content, which change to reflect the data the CPU will probably ask for in the near future. The CPU normally fetches content from the cache, but does not rely on it: cache misses happen every second.
Still, the hardware cache system have enormous advantages, because most of the time the CPU requests are fulfilled without reading Ram. When central memory access is necessary, data is still available transparently (only more slowly) and the control unit of the CPU can theoretically be agnostic on the cache (but in practice it has to know it very well for optimization reasons).
An hardware cache is so advantageous that commonly there are multiple levels of it in a system (named L1, L2, L3). Another form of cache is the virtual memory implementation.
Degradability is present in every cache since the circuits that it is composed of are costly, and the hardware engineers are satisfied of enhancing data access performance for the local references. When there is a jump to a far routine, the access time is degraded.

A degradability pattern is present in the web, that takes care of compatibility with all the devices that forms the cloud: mobile phones, desktop machines, PDAs, old web servers and browsers. When you are working on javascript widgets or a Flash site, think of the users that do not have the resources to use it.

Featured post

A map metaphor for architectural diagrams

It is a (two-dimension) representation of a pipe. The map is not the territory , but in software engineering terms they are models of it....

Popular posts