The JavaScript blog.

AuthorThe Angry JavaScript Nerd

node underscore

Underscore, Array.prototype, and You

Posted on .

What's the most dependent module on npm? Underscore.js! Why do people use it? Presumably because they can't be bothered to learn how JavaScript works.

There are things I like about Underscore. No global meddling, sane internals -- it's a solid piece of work. But I occasionally find myself working with programmers who are probably better than me yet have weaker JavaScript skills, and they reach for Underscore like a drunk reaching for cheap gin.

At this point I stay their hand and point to Annotated ECMAScript, highlighting the superpowers baked into Array.prototype. Granted it lacks some of the things Underscore has, but it often does what you want.

Mozilla's documentation is also good because it shows you how to duplicate the functionality with lengthy code samples, which is educational if you take the time to read it.

If this is new to you or you're a little uncomfortable with Array.prototype, start with forEach then map and some. They're the methods that crop up in my own code a lot.

Another related JavaScript quirk is array type checking. Because JavaScript says typeof [1, 2, 3] is 'object' you might want to pack your bags and give up altogether. I don't blame you. But hiding in that ES5 documentation is a beastie called Array.isArray. You'll find it in util in Node, which is puzzling -- you'll be OK using Array.isArray([1, 2, 3]).

I don't think it's a bad thing to depend on Underscore, but it makes me feel like people don't learn Node or indeed JavaScript well enough before flinging their modules up on npm.


node modules yeoman rants

Static Site Generators for Yeoman

Posted on .

I often find myself being the only guy in the team who can make (or wants to make) a good ol' fashioned website. No dynamic stuff, just a simple static marketing site to sell a product. "No problem," I say confidently, dreaming up designs I can implement rapidly with Vim, Bootstrap, and Glyphish.

The problem I've ran into consistently over the last year or so is Yeoman doesn't do what I think it does. This is what it does in my head:

  • Unites Grunt, Bower
  • Runs a little web server so I can see my site without having to run a web server
  • Doesn't install any Ruby nonsense
  • Uses idiomatic Node

Here's what it actually does when I use generator-webapp:

  • Installs loads of weird stuff I don't need to do with testing and image optimisation
  • Make a Gruntfile.js that isn't formatted using the coding style of most community Node projects
  • Seems to need Ruby due to Sass when I make it install Bootstrap

Then I realise generator-webapp might not be for me, so I try starting a project from scratch. Then I get into an incredible mess trying to automate the minimization of each Bower component's JavaScript, CSS, and copying assets to a suitable location with Grunt.

I Miss Makefiles

Here's how you copy a file in the shell:

* cp tmp/*/*.min.js site/js/

Here's how you do it with Grunt:

copy: {  
  dist: {
    files: [{
      expand: true,
      cwd: 'tmp/',
      src: ['*.min.js'],
      dest: 'site/js/',
      filter: 'isFile'

Not only is it a whole bunch of lines to do something that should be simple, it also has weirdly named properties. I see isFile and start an internal monologue about everything being a file because it's Unix.

I could write a Makefile in two lines that does this.

Yeoman Static Site Generators

This time I decided to persevere: I tried a bunch of static site generators for Yeoman.

  • Armadillo: Installed lots of stuff I didn't need, and needed Ruby
  • Go Static: Was more for blogs than simple sites, and seemed to make files indented with tabs

There were more but I only have bad things to say about them. What I ended up with was this:

  • grunt-contrib-connect for running a web server. It was more complex than it needed to be because it defaults to exiting automatically rather than running a server, you need to specify a keepalive setting
  • grunt-contrib-concat for concatenating Bootstrap's CSS, JavaScript, and any other dependencies in bower_components
  • grunt-contrib-copy for copying the files from bower_components to my website's asset directories

The Shit Sandwich

I think the reason I have difficulty with Yeoman and Grunt is I see client-side development as "open source stuff" and "my stuff". I want open source stuff poured out into buckets that I never look at, in a way that's easy for other people to repeat should they want to install the dependencies fresh (I keep the files in the repository), or experiment with upgraded versions of each module.

Conversely, my stuff should be elegantly encapsulated with a module loader like RequireJS, kept separate and decoupled.

Instead of a neatly organized bento box with very clear sections I end up with a shit sandwich.