TypeScript as ES2015/ES2016+ compiler

I frequently encounter packages on NPM which bring in Babel to compile ES2015/2016+ down to older JavaScript suitable for a wider range of browsers. Babel is a very effective tool for this, it has been around quite a long time, and is highly configurable and flexible in future ready. It has an amazing community and reputation.

But – it is also surprisingly “heavy” in its impact on your tools installation. A typical Babel installation with a typical set of plug-ins can easily bring in 20,000 or more files, spread over hundreds of transitive dependency packages. On a huge project this might not be noticed, but on a small or medium project it can easily be the largest dependency.

Are large NPM dependency trees a problem? Theoretically no, but practically they have some downsides. Dependencies bring risk, and lots of dependencies inevitably bring more risk. If you depend transitively on hundreds more packages, your project is more vulnerable to the sort of NPM vagaries that happen from time to time (the most famous being left-pad), your project is more inclined to fall behind current versions, and most annoyingly in corporate settings, that long list of plugins and transitive dependencies is more likely to cause heartburn among lawyers who evaluate licenses.

There is an easy way to ease this problem, but it involves a minor update to one’s thinkinh. Find the spot in your mind where you may think:

“the TypeScript compiler is a tool for compiling TypeScript code to JavaScript and type checking it”.

The actual truth in 2017 is:

The TypeScript compiler is an excellent, well supported, frequently-updated general-purpose tool very suitable for non-TypeScript users. It does a great job compiling a broad array of standards-path ES2015/16/+ features down to ES2015 or ES5. It fits in well with overall project build tooling. It is completely suitable to use the TypeScript compiler on a non-TypeScript project for this purpose.

The TypeScript compiler has several substantial practical benefits over Babel:

  • It is a single dependency with no transitive dependencies.
  • Usually faster compilation.
  • It is developed by a team at Microsoft, who do a great job grinding away at the boring aspects of this work, shipping a long series of updates which keep fixing bugs and adding features.
  • It installs quickly and has far fewer failure modes in installation (because of no transitive dependencies).
  • Just one open source license to review (no transitive dependencies)… from a company that your company probably already buys a lot of stuff from anyway.
  • Just one version to update, and one configuration file to tweak which features you are using.
  • WebPack and other plug-ins available, quite analogous to Babel.

As of 2017, my recommendation is to consider TypeScript as the default solution for compiling ES2015/16+ code in non-TypeScript projects, and use Babel as a fallback if your project needs cutting-edge features that are (intentionally) not yet in TypeScript.

Pug (formerly Jade), in the browser?

 

Over at Oasis Digital Angular Boot Camp, we teach Angular 2+ using tooling that operates entirely in the browser. It compiles TypeScript to JavaScript, it processes a module system, etc. This works very well, and makes for a fast, easy setup and edit/run cycle during class. Great stuff. (We also teach the use of heavier duty server-side tooling like Angular CLI; but CLI is still short of the convenience in-browser tooling.)

I recently wondered whether might be possible to support some of the other tools we use, in the browser. Many useful tools in the JavaScript development ecosystem (including Babel, TypeScript, and many others) are implemented such that they can execute in either a browser environment or in a server (node) environment. This appears to not be a great technical challenge, for projects intended to work this way. The aspects which require node APIs (such as talking to the file system) are simply implemented and wired up separately from the core functionality – which is “just JavaScript”.

Unfortunately, this plan didn’t get very far: the tool I wanted to add next is Pug (formally known as Jade). Pug is currently implemented using Node APIs scattered throughout the code base, rather than in a universal node/browser way. I noticed an open issue asking about this, but it appears there is not interest in achieving such a thing.

Browsing around the Pug code base, it appears would be a moderate amount of work to reshape things to make this possible; but it would involve small changes widely scattered around the code. That kind of change is generally frowned on the project unless there user and developer eagerness for the feature in question. Therefore, I am curious, readers of my blog: is there much interest out there, enough for someone to consider maintaining a fork of Pug converted to universal JavaScript? Or a wrapper/shim around it, to stub Node APIs sufficiently for Pug to operate in the browser?

More CSS in JavaScript, this time with React

In September I mentioned a talk at Strange Loop 2014 where the speaker described a technique for writing CSS in the form of JavaScript which then executes to produce the actual CSS. This avoids a server-side build process, it knows more about the browser while operating, it avoids a HTTP round-trip, and has various other advantages. However, the tooling the speaker was talking about was closed source inside of the conference speaker’s product.

Today I encountered a presentation online by a React expert at Facebook, who uses React’s mapping from JavaScript to HTML+CSS, to accomplish many of the same things and more – using tools openly available.

If anyone knows of a audio or video recording of the talk, I would appreciate a link very much.

My own experiments with programmatic CSS also react, but behind ClojureScript, so I’m writing Clojure code which turns into CSS. It is not as mature as what is described in the slides above, but it adds yet another layer of abstraction in the form of a higher-level language.

FlightJS, an event-centric JavaScript library/framework

Are events your favorite part of AngularJS?
Look at FlightJS instead.

Angular’s Event System

At Oasis Digital, we use AngularJS for most of our client-side “SPA” web development. AngularJS is well suited for data and form centric enterprise web applications we most often work on; I’ll write more about why we chose AngularJS another time.

As we teach our Angular Boot Camp class, we spend time on the AngularJS event system. For those who haven’t looked at it, AngularJS’s event system operates at a higher, more abstract level then DOM events – AngularJS events propagate up-and-down AngularJS scopes rather than up-and-down the DOM directly. We typically recommend it only for narrow cases where some bit of information should be transmitted and responded to broadly across the application; it avoids the computational cost of numerous watches.

In both these classes and our development work, we sometimes meet developers who are very excited by the AngularJS event system, and endeavor to create an event-based application with it. We must then unfortunately give the following disappointing advice:

If you are looking to build a mostly event-based system, AngularJS is probably not the right tool for you. There are a lot of merits to events, but the event-centric approach is not the AngularJS way. If you’re going to build primarily with events, you are wasting much of the AngularJS ecosystem, which is primarily about scopes, data binding, directives to enhance HTML with technology and domain specific add-ons, and so on.

DOM Events Find a Home

But that is not to say events are bad. Events are great. Don’t lose hope. There is a home for you: Twitter’s FlightJS.

FlightJS is 100% event centric and DOM-centric; it embraces the browser DOM with minimal abstraction. FlightJS is tiny – according to its website “Flight is only ~5K minified and gzipped. It’s built upon jQuery.” FlightJS fits in well with JavaScript ecosystem; because it adds so many fewer features than one of the big frameworks, there is little to get in your way of using it with any other common tool. Based on a quick look at its mailing list and GitHub repo, is getting a small amount of traction, though perhaps much less so than the big frameworks.

Here at Oasis Digital, we are not switching to FlightJS, and we don’t force an event centric approach on our AngularJS work, in which we aim to stay squarely in the mainstream of AngularJS practice. But if something comes up where events are the right solution, we know where to look, and now you do too.

 

Dynamic CSS Manipulation with JavaScript

Last week I attended the Manning’s Powered By JavaScript one-day conference, the day before Strange Loop. Here are some thoughts on the “Powered By” conference as a whole and on one talk:

Dump Less and SASS: Dynamic CSS Manipulation with JavaScript
Speaker: Michael Mikowski

I wrote recently about CSS, so this talk caught my attention more than any other that day.

Powered By JavaScript Mini-Review

Overall this mini-one-day conference was well executed:

  1. Interesting speakers
  2. Good venue
  3. Very convenient to attend the day before Strange Loop

But I would like to call out a few opportunities to improve:

  1. The registration process was slow, and understaffed. The team running the conference should be able to look at the number of attendees and staff the registration process based on it.
  2. The registration process included registration for speakers in the same line as attendees. As a result, when a speaker reached the front of the line there was a long diversion while the staff was excited to greet and visit with the speaker. That is a wonderful way to treat speakers; but they should be diverted out of the way of the hundreds of people standing in line behind them to just pick up a badge.
  3. This one-day conference was co-located with Strange Loop, so the planners should expect a lot of Strange Loop people there – and plan for students at roughly the same skill level. Unfortunately the JavaScript event was targeted toward less sophisticated developers than typically attend Strange Loop.
  4. Please watch the clock. Many of the speakers did not end at the appointed time.

That sounds too negative. This was a very good effort from Manning, and I recommend attending future Manning JavaScript events.

Diversion #1: The Book

The speaker Michael Mikowski is the co-author, with another speaker at this conference (Josh Powell), of the book “Single Page Web Applications: JavaScript end-to-end”. Based on what I heard at the conference, this book is a little behind the times compared with today’s toolsets. I don’t believe it mentions the current competitive tools out there like Ember, AngularJS, React, and so on. Rather it seems to be about good practices for using an older generation of tools. Still, this was a distraction, because the speaker was fantastic!

Diversion #2: The Speaker

I had not met or seen a talk by Mike Mikowski, but from a look at his website he is a sharp fellow with very interesting things to say. In particular, I wish I had been at his “Fog of SPA” talk; the slides are worth reading, and I wish there was a video to watch, those slides were probably backed up by great stories. (I don’t necessarily agree with every idea in it, though. For example, I find it usually is worth having a build process to use higher level tools.)

This Talk: Dynamic CSS Manipulation with JavaScript

To summarize briefly, the message of this talk was that writing Javascript to emit CSS can replace LESS, Sass, and other CSS tools. Instead of adding another language and server-side build process (for Sass or LESS) to address weaknesses in CSS, you can write JavaScript code which emits CSS, and run that JavaScript code on page load or when needed. There are several important bits to get right to make this performant, for example the CSS for a page should be swapped out all at once to avoid the browser repeatedly re-rendering.

I don’t recall if the talk was recorded on video, but if it appears online, watch it.

As is my (unfortunate?) custom, I will first review a couple of nitpicks:

  • The title of the talk was mis-capitalized as “Dump Less and SASS”, which gets the name of Sass wrong. (Until earlier in 2014, Less was called LESS, incidentally.)
  • I waited anxiously for a glorious revelation in which code that would appear on the slides. Unfortunately, code never appeared. Mike convinced me to consider this idea in the first few minutes. I was ready to look. Please show me code!

Now on to the good stuff. Mike’s idea is interesting and appealing, and perhaps compelling for certain types of web applications. Clearly for the application Mike and friends are building at Qualaroo, it is an ideal and very slick application of technology. Particular appealing ideas:

CSS responsiveness by means of media queries can only respond to the narrow-ish set of information available to a media query. This JavaScript CSS approach can respond to any information at all available to the page, including (for example) the current zoom level.

LESS and Sass offer a good set of abstractions, a big improvement over vanilla CSS. But they only offer what is in their respective boxes. With a JavaScript CSS approach, as a developer you can create whatever specific set of abstractions is valuable for the problem at hand in a specific application.

The JavaScript CSS approach does not need a server-side build process, because it simply runs a little bit of JavaScript in the browser on page load.

The JavaScript CSS approach reduces the number of HTTP requests to load content; the CSS arrives (in a “compressed” form, in the sense that JavaScript to write the specific CSS is probably smaller than that CSS) as part of the JavaScript request.

If you generate CSS programmatically, you don’t have to stop at JavaScript. You can use CoffeeScript to generate JavaScript which generates your CSS, for example.

Actual Code!

Fortunately, while this talk did not include code, there are plenty of other people online doing something vaguely similar, who do publish code. Here are some I found. It is great to see this approach is already out there is common use, not a proprietary invention!

http://www.responsivejs.com/

http://absurdjs.com/

The following are also similar, but for Clojure. There are numerous ways to write your CSS in a different language (JS or otherwise), which already have variables and subroutines and other useful features.

https://github.com/paraseba/cssgen

https://github.com/rathwell/clj-style

https://github.com/noprompt/garden

Data Services for AngularJS Applications

I wrote recently about data/API services for complex “single page” JavaScript-heavy web applications. Everything there applies to AngularJS as well as other frameworks (Ember, Knockout, React, etc.), but there are some particulars to keep in mind for ease of interaction between an AngularJS web application and a data service. This topic is also asked about in almost every “Angular Boot Camp” class I teach, so by posting this I have an online resource to point at.

Use RESTful URLs and HTTP Methods

By following RESTful patterns rather than inventing ad-hoc patterns for a server API shape, your code will fit in more easily with the rest of the software industry. This reduces the friction in bringing on more developers, in integrating your application with others, and so on. A RESTful server API will operate easily with AngularJS’s built-in mechanisms for working with a server, whether you use plain $http, $resource, or Restangular. For example, all of those already assume that the HTTP status codes indicate success and failure, so do not make up your own way of encoding failure within HTTP “200” success.

Avoid dogma in REST design, though. Most of the time, you can make a server API shape reasonably RESTful with approximately the same implementation effort as something ad hoc. If you have a case where a RESTful design will require substantially more work than something else, consider an “escape hatch”: a portion of your API that isn’t particularly RESTful, hidden behind a generic POSTable endpoint.

Make Data Binding Easy

I assume that by choosing AngularJS, developers aim to leverage its strengths rather than fight it. That means embracing “HTML enhanced”, data binding, and other banner AngularJS features, rather than manually manipulating the DOM (which immediately fails code review here), mostly passing information around using bindings and $watch rather than events, etc.

Therefore, if possible make your data service return data in a shape already suitable for binding in your AngularJS application. Done well, this can reduce the amount of JavaScript code you must write to populate a complex screen to almost nothing. By complex, I mean a screen which contains the modern equivalent of numerous master detail relationships, hundreds of fields, etc.

Of course, JavaScript is a powerful and convenient language for data structure manipulation, so in a sense it does not matter what shape of data is returned from a server; it is always possible to process that data into a shape suitable for data binding. Hence this guideline is oriented toward ease and speed of development when the server code is being written fresh.

(As an aside, I am not 100% sold on data binding; there are other approaches, like that taken by React, which have significant advantages. But if you are using AngularJS, embrace its strengths. Use data binding pervasively.)

Make Commands / Saves Easy Also

Following along from the above, a conveniently and idiomatically crafted AngularJS application will typically yield JavaScript data structures suitable for PUT or POSTing back to a data backend. Make your server accept PUT or POST of updated or new data in the same object “shape” as it returned data. This way, the data can make a round-trip from the server, through data bindings, to be manipulated by a user, then back to the server; all with very little code to write.

This applies to commands (in the CQRS sense) also. If a user is working with the screen via data binding, then that data binding can often yield a data structure ready to send to a server with a couple of lines of code. If you find it necessary to write extensive lines of code to formulate a server interaction, perhaps either your data binding or server should be adjusted stat.

Consider NodeJS on the Server Side, for Code Sharing

Working with complex client-side web development, you will almost certainly use NodeJS in your development toolchain, even if you are not using NodeJS for your data services.

But NodeJS is worthy of consideration for this key reason: it enables code sharing between the front end and back end. With some care in crafting modules, chunks of functionality which must be implemented on both sides of the client/server API (such as validation, but also many kinds of domain logic) can be reused across both, ensuring consistent implementation and eliminating duplication.

There are numerous other platforms worthy of consideration for other reasons. Stay tuned here (and follow me on twitter), I will have more to write about that.

Guard Your Innovation Budget

If your organization is in the process of adopting AngularJS for the first time, consider not simultaneously adopting a new server-side technology. As humans we each have a certain ability to absorb change, and doubly so for organizations comprised of many humans working together. You will probably get better results if you switch to a new client-side development toolkit in a different year then you switch to a new server side development toolkit. I think of this as having an “innovation budget” which can either be concentrated on one layer at a time, or diluted across more than one layer.

Help Wanted

If anyone knows of convenient source code examples already online of doing these things well versus poorly, please contact me – I would love to add links. Given sufficient time I may create the examples, but with the pace of change in our industry these tools could be obsolete before that happens!