Reading the Classics: JavaScript – the Good Parts

I read Douglas Crockford’s JavaScript: The Good Parts over the long weekend. My interests were partially pedagogical. A huge part of my current job involves mentoring more junior developers and helping them to learn. One of my interests was whether Crockford’s book would be a good resource to pass along. It seems like a silly question. The book is still the book best known for putting JavaScript on the map as a quasi-respectable language. I learned JavaScript the way I have learned most languages which is to say, in the school of hard knocks. I had learned most of the good and bad parts of JavaScript through trial, error, Google and JSLint. The book wasn’t a bad refresher, but there weren’t a lot of new insights, either.

The timing makes the question genuinely difficult. ECMAScript 6 is out and some of the features are available now, more are available through polyfill and most of the rest could be acquired through Babel (https://babeljs.io/).

The book is, in a sense, almost obsolete. Almost. A good example of what I mean is prototypical inheritance. Crockford spends a lot of time explaining how class-based inheritance is different than prototypical inheritance. This is still relevant. JavaScript has remained a prototypical language. He also shows several techniques to make the meaning of JavaScript programs more clear to those used to classical object-oriented programming. This part is less relevant. Today, I would reach for the ES6 class syntactic sugar (via Babel for the browser) or CoffeeScript rather than layering some manual code over the prototype.

Similarly, Crockford discusses variable scoping at length. Again, this is partially relevant. The base scopes haven’t changed and they still easily trip up many programmers (I have used questions about JavaScript scopes to trip people up on interviews). These things need to be understood. However, the let statement in ES6 does provide some clearer semantics and its use should be encouraged as ES6 becomes widely available.

There are also new parts which, good or bad, require some level of explanation. Generators and promises will require explanation and, of course, categorization as either good or bad parts.

This sort of thing leaves me in a place where I want to recommend Crockford, but I feel the need to add some general commentary. Hopefully, a second edition of JavaScript: The Good Parts will come out in the next few years and make these little oddities of time go away.

Weighing in on JavaScript Package Managers

I have quite recently begun work on an open source project with a node back-end and front-end work planned to be done in React. This is my first full effort to work with the latest and greatest in JavaScript tooling. We use Ext JS and Sencha Cmd at work and, whatever else you want to say about that stack, it is different. My last full blown front-end development was before the real Node boom and I pretty much did it the old fashioned way — namely, downloading minified JavaScript by hand and referencing it in my markup (shaddup ya whippersnappers).

JavaScript saw a real explosion in package managers a few years ago, which was a natural place to go from a growing ecosystem to have none. Market forces naturally took over and many of the earlier examples have been culled out of existence. There are really two main options at this point: NPM and Bower. Bower has enjoyed a healthy following, but (by my entirely unscientific survey), it appears as though the NPM uber alles faction within the JavaScript world is growing stronger.

The sentiment is echoed in other places, but http://blog.npmjs.org/post/101775448305/npm-and-front-end-packaging gives a good overview of the fundamental syllogism. It basically goes that package management is hard, NPM is large and established, so you should use NPM everywhere rather than splitting package managers.

The argument has a certain intrinsic appeal – after all, the fewer package managers, the better, right?

The real problem is that it is possible to use NPM as a front-end package manager, but it is deeply unpleasant. Systems like Browserify and Webpack are needed to prepare dependencies for usage on the front-end. These are complex and, to a degree, brittle (I ran into https://github.com/Dogfalo/materialize/issues/1422 while attempting to use Materialize with an NPM application).

Even if one assumes that every package can ultimately be Browserified (and it doesn’t seem like an overly-optimistic assumption), the effort seems to be pure waste. Why would I spend time writing complex descriptors for modules on top of their existing packages? For it’s shortcomings, Bower seems more robust. I spent a few hours fiddling with Browserify and Materialize without much success (although I think I do see how browserify would work now), but mere minutes wiring up Bower.

This does not get into the fact that Browserify/Webpack require additional information to extract CSS, images and web fonts. Even when things are working, it would require constant effort to keep it all up to date.

At the moment, NPM, even NPM 3, simply does not have good answers for setting up front-end development. The NPM proponents really, in my opinion, need to focus on making front-end modules more effective rather than pushing tools that are little more than hacks, like Browserify and Webpack. At this point, I am just going to rock out with Bower. Maybe someday I will be able to trim out Bower — but I would rather spend time coding my application than giving NPM some TLC.

jqGrid Frustrations

I just got a jqGrid (not my first, I might add) put together that took way too much time. While I am going to go back and add some features now, I was struggling to get the blasted thing to do the easiest task in the world: show some data. That’s it. No paging. No searching. Nothing fancy, just show the data.

  1. $(document).ready(function() {
  2.     $('#grid').jqGrid({
  3.         url: 'my_callback.php',
  4.         datatype: 'json',
  5.         colNames: ['col0', 'col1', 'col2', 'col3', 'col4', 'col5'],
  6.         colModel: [
  7.             {name: 'id', index: 'id', width: 50},
  8.             {name: 'foo', index: 'foo', width: 200},
  9.             {name: 'baz', index: 'baz', width: 100},                                        
  10.             {name: 'quuz', index: 'quuz', width: 150},                                            
  11.             {name: 'bar', index: 'bar', width:150},                                        
  12.             {name: 'schnoodle', index: 'schnoodle', width: 150}
  13.             ],
  14.         mtype: 'GET',
  15.         rowNum: 20,,
  16.         viewrecords: true,                                                                              
  17.         imgpath: '../javascript/themes/basic/images',                                                  
  18.         caption: 'My Caption',
  19.         });
  20. });

Where, of course, a few of those items have been anonymized. As vanilla a set up as you could ask for. I agonized over the JSON data, making sure it matched the default JSON reader (which, I might add, I used last time I used this component). Finally, trial, error, and Google prevailed. This is the code that worked:

  1. $(document).ready(function() {
  2.     $('#grid').jqGrid({
  3.         url: 'my_callback.php',
  4.         datatype: 'json',
  5.         dataType: 'json',
  6.         colNames: ['col0', 'col1', 'col2', 'col3', 'col4', 'col5'],
  7.         colModel: [
  8.             {name: 'id', index: 'id', width: 50},
  9.             {name: 'foo', index: 'foo', width: 200},
  10.             {name: 'baz', index: 'baz', width: 100},                                        
  11.             {name: 'quuz', index: 'quuz', width: 150},                                            
  12.             {name: 'bar', index: 'bar', width:150},                                        
  13.             {name: 'schnoodle', index: 'schnoodle', width: 150}
  14.             ],
  15.         mtype: 'GET',
  16.         rowNum: 20,,
  17.         viewrecords: true,                                                                              
  18.         imgpath: '../javascript/themes/basic/images',                                                  
  19.         caption: 'My Caption',
  20.         });
  21. });

See the difference? That’s right. There is a datatype entry and a dataType entry. Mind you, when I took either of these away, the grid broke in some way. Leave them both, it is fine. A quick grep of the code shows that, predictably, after this angst, parts of the code use datatype and other parts use dataType. JavaScript is case sensitive, so it matters. Now, the version of jqGrid in the code base is not the newest, but at v. 3.2.4 it should have been pretty stable. No doubt an upgrade would fix this (all right, after this I do have some doubt), but I am ticked. How could no one have noticed this after 3 versions? It’s not like I downloaded version 0.01. Or was running an SVN bleeding edge edition. It failed on an exceptionally simple example. jqGrid is a nice component, over all, but far, far too brittle.

PS – the link that put me on the right trail is here: http://stackoverflow.com/questions/259435/jqgrid-with-json-data-renders-table-as-empty.