Software! Math! Data! The blog of R. Sean Bowman
The blog of R. Sean Bowman
February 09 2016

I have been writing some Javascript lately, mostly in my free time. Don’t ask me how I got started – Javascript is not my favorite language, let’s say, and I don’t do a lot of web stuff these days. But it’s been interesting to check out the landscape. There are more “frameworks” than you can shake a stick at, the language itself is evolving pretty quickly, and there are lots of cool things you can do in the browser that weren’t available even a couple of years ago.

First off, I don’t have entirely positive feelings about the whole nodejs explosion. I understand the desire to use one language on both sides of the network, which I guess is what node was originally about. On the other hand, as I said before, Javascript is not my favorite language. There are many places to read people’s opinions on the matter; I like Rob Ashton on Javascript and Node, and I have some pretty strong sympathies in that direction.

But no matter: my goal is using javascript in the browser, not as a server or general purpose language to (shudder) write command line applications in.

NPM/Browserify

Ahh, but that’s the issue: all the newfangled tools for fixing up your javascript, rendering templates and css, bundling it all up to ship out and so forth are based on node, and in particular the node package manager, npm. So you’re sucked in right from the get go unless you want to go really bare bones.

I was prepared for pain and torment, but I have to say that npm is actually pretty cool. (There’s plenty of pain and torment below, don’t worry.) Npm has

  • a huge ecosystem of packages,
  • easy to install packages and dependency handling that must be pretty good (because I haven’t yet had any trouble with it),
  • low barrier to entry in the form of a package.json file that can pretty much be generated for you if you like.

It has some downsides, too; finding a package that does what you want is sometimes fraught with difficulty because there are many that do the same thing and lots of them are out of date.

But the idea of node packages and npm is that there should be lots and lots of small packages that perform one bit of functionality well. When you need to do something (parse dates, generate yaml, find the median of a time series), you just look up a package, install it, and start using it from your code. There’s nothing fundamentally different from this and, say, Python’s pip or cabal for Haskell. But, the feeling is different, more like small composable bits instead of “packages” that perform some larger role in your application. I’m not entirely sold, especially with all the junk/unmaintained/tiny/useless packages available, but npm does a lot right.

The other tool I’ve been using a lot is browserify. This is a utility that lets you take code which is ostensibly written as server side nodejs code and package it for the browser. Of course, I’m not thinking of doing anything other than packaging my Javascript to run in a browser, but it turns out that the server side Javascript folks have some nice tools available for structuring their code, like modules and other features not available in browsers (see Babel discussion below). Browserify lets you use these in your browser code and hides the details of getting everything to work.

Modules, package managers, bundlers

At this point I should say that the new language version ES6 has a nice module system… but there are no browsers that support it (yet). Plus, one of the points of the module system is to include as few dependencies in the files you make your users download. (Warning: the link is to the ECMA language specification, completely boring, do not read.) For example, if you include the function foo from the module giant_module, it would be nice if a tool like browserify could only include the code for foo and its dependencies, instead of including the whole giant_module (as it does now).

There are tools that aim to do this today, but they… fall short, let’s say, in my opinion. Jspm, webpack, and rollup all lay claim to being the next generation browserify/package manager/vegetable peeler. Frankly, I haven’t gotten them to work at all; my experiences range from difficult to configure (webpack) to downright not working (jspm). Now these are new tools with ambitious goals, and I’m not complaining, I’m just saying they’re not for me, right now, today.

Goofy build tools

And don’t get me started on grunt, bower, gulp, and whatever other goofy build tools there are. I don’t understand these well enough to make criticisms, but I will anyway: these are “build systems” that tell how to do something instead of what to do. We have had make with all its warts for decades now, and no matter what bad things you can say about it, it has a declarative syntax and does incremental builds. Works great for small and medium size projects. It works for large projects, too, it’s just ugly.

Gulp, on the other hand, needs to be told exactly what to do in an imperative way. The simplest “gulpscripts” seem to be hundreds of lines long. There are lots of articles these days on “using npm as a build tool,” which is pretty funny, because what these people are talking about is using a feature of npm whereby you can run “scripts” kept in your package.json file. For example, instead of running browserify src/main.js -t babelify --outfile dist/main.js on the command line, I can stick that in my package.json file, give it a name (build, say), and then run npm run build so I don’t have to remember all the options and so forth. Pretty primitive stuff, right? Basically just a few shell scripts. On the other hand, it works way better than writing tens or hundreds of lines of code just to minify some css and Javascript.

Transpilers

One reason people point to for needing such build tools is that there’s lots of “transpiling” going on. This is because systems like node support newer versions of Javascript than the browsers (which will always be behind; plus you have to write for that one guy who still uses IE 8 and so forth). To get around this, various tools compile language extensions down to regular old vanilla Javascript 5. I have been using Babel, and I have to say I like it. There are a couple of features of ES6 that are worth having (abbreviated anonymous function syntax is certainly one). Babel is a way to get those benefits without worrying about browser support. Plus, it’s relatively easy to integrate into the npm/browserify toolset.

(Note also that the word “transpiler” causes some people to become apoplectic. I’m not one of those, although I see where they’re coming from.)

Here are some of the most basic features of ES6 I enjoy: const and let introduce variables; much nicer than var. The “fat arrow” syntax for creating anonymous function is much nicer: compare

[1,2,3].map(function(x) { return x*x; });
// vs
[1,2,3].map(x => x*x);

The module system, as I mentioned above, is nice. Finally, I’ve been playing with Promises, which are a way to escape “callback hell” so familiar to Javascript programmers.

While I’m on the issue of compilers and such, I should mention a very cool system called sweetjs which lets you write hygenic macros for Javascript. Of course, it’s more difficult in a language like JS than good old homoiconic lispy languages, but nonetheless people have done some pretty astounding things with it.

Overall

Javascript still isn’t my favorite language, but I have enjoyed learning what’s going on in that space, and some of the tools are pretty cool. I’m happy with npm/browserify/babel for my current needs, and it looks like there will be even better options in the future. I’ve been playing around with some of the newer frameworks and libraries… but that will have to wait for another post!

Approx. 1347 words, plus code