Transpilers, parsers, and shims

My current build process for PubReviews.com utilizes Grunt.

On occasion I have seen 'Esprima' outputted within my build logs.

I have always been happy to allow the internals of the tools which I utilize for build and release cycles to keep their internals relatively hidden.

That was until today..

Having spent a large majority of my time working on other projects, I have not been keeping up to date with open source developments.

The Pub Reviews project utilizes React for its client side, but was back in the stone age utilizing 0.11. As such I decided that I would get myself up to date with recent developments, gain a more thorough understanding of some of tools I am using (behind the scenes), and document it here.

Transpilers

As defined by Wikipedia:

"A source-to-source compiler, transcompiler or transpiler is a type of compiler that takes the source code of a program written in one programming language as its input and produces the equivalent source code in another programming language."

JSTransform

Historically one could write their code in JSX and then convert it into pure javascript utilizing a transpiler (as part of a build process) or an on the fly conversion process.

Utilizing the JSTransform tool that was packaged as part of react-tools, one could utilize a command such as sudo jsx --watch jsx/ js/ --extension jsx to watch all changes to JSX files in a given directory, and convert them on the fly.

Such a setup allows quick development iterations without have to compile JSX inline/on the fly.

As of 0.14, this has been deprecated along with react-tools (see here).

Babel

Babel is the transpiler that is currently recommended for use by the React team (as of 0.14).

It converts JSX into Javascript as well as a number of other transformations to make sure that the code you write works in all currently available environments. For example it converts ECMA6 syntax into syntax that will work in the current browser iterations.

It also provides a browser version which completely replaces JSXTransformer for those of you were converting JSX inline on page load.

Parsers

Esprima

Esprima is a parser which takes your Javascript code and parses it into a semantic explanation formatted as JSON (an Abstract Source Tree (AST))

It is useful for parsing code for utilisation within IDEs (autocompletion) as well as for transpiling code - it is the parser utilised in JSTransform.

It allows for code that is never used to be discovered (and removed) alongside various forms of syntax validation. It can then be converted back to Javascript code utilising escodegen.

Whereas a linter (for example jslint might check that certain stylistic standards are followed, the Esprima pass validator simply makes sure that the Javascript engine will understand it. It does not have to be good code. Esprima even provides an online code validator which you can have a play with.

One of many

Whilst Esprima is the parser that has been popping up in my console, there are in fact many alternatives. For example acornjs, AND UglifyJS 2.

AST Formats

Both Esprima and acornjs utilize the Spider Monkey AST. It is a well documented format, developed in house over many years by Mozilla. UglifyJS2 utilises its own AST for reasons outlined here.

Shims

Whilst the title 'Shims'is pretty generalised, they are an important part of my build process.

The definition of a 'Shim' as told by Google is:

"a washer or thin strip of material used to align parts, make them fit, or reduce wear".

In software, it is exactly the same - it is a tool (piece of code) that allows for code utilising one API to interact with code utilising another API. It is the adapter aspect of the adapter design pattern.

Within my codebase I utilise browserify-shim, and my own set of shims for working with PhantomJS.

browserify-shim is designed to "Make CommonJS-Incompatible Files Browserifyable". It allows me to make libraries (jQuery, bootstrap etc) that are loaded from CDNs (and are thus in the global scope) accessible to browserify such that I can build my javascript for utilisation in the browser using simple require calls.

Interestingly, browserify also works by building an AST and parsing it to build up a graph of dependencies !

Because I utilise PhantomJS for the functional testing of a number of my projects, I want the browser environment in which I test to be as close to the browsers than people ctually utilise to access my products. PhantomJS 1.9.2 did not support Function.prototype.bind natively (here is why), so I was required to utilise a shim (polyfill) implementation of the bind method to make calls to the method work within my test environment.

Obviously, adding code purely for testing is not ideal - this was always a temporary solution. Fortunately as of PhantomJS 2 this is no longer a problem and as such the shim has been removed.

Conclusion

So there we have it. A brief overview of some interesting tools/concepts that may be of use to you whilst building your projects. If there are any topics that you'd like to read about, please let me know and I'll do my best to blog about them!


Thomas Clowes

Thomas Clowes

I am a 28 year old software engineer from the United Kingdom. During the day I build multi platform applications. In my spare time I eat food and run marathons. Sometimes I write angry tweets.