As I said recently, I’m experimenting with writing a Netrunner implementation in JavaScript. I’m calling it Medium; here’s the first in a series of posts about issues I’ve encountered along the way.

Before I go too far, I want to thank two sources of information. The first is Bill Lazar; he’s one of my coworkers, and he’s given me lots of useful advice. (And I suspect still more advice that will be useful once the project gets more complicated.) The second is James Shore: just as I was thinking about starting this, he published a list of JavaScript tool and module recommendations that seems very solid.

Anyways: before starting, I’d made a couple of technology decisions, and they were actually to not quite use JavaScript and CSS: both are solid technologies to build on, but both have annoying warts that I don’t think are worth spending time to deal with. So, in both cases, I’m using languages that are thin wrappers around them: instead of JavaScript, I’m using CoffeeScript, so I don’t have to worry about building my own class system or explicitly saving this in a local variable when I’m passing a function around. And instead of CSS, I’m using Sass (or, specifically, SCSS): when writing CSS, you find yourself repeating certain values over and over again, so having a macro layer on top of CSS can really improve your code. Neither of these languages means that you don’t have to understand the language that underpins them, or means that you need to have to learn extra concepts beyond what the base language provides: they just automate some common tasks.

(Incidentally, once my CSS gets more complicated, I’ll probably start using Compass as well. I haven’t yet felt a strong need for that yet, and it’s possible that what I’m doing is simple enough that I won’t actually need Compass, but it seems like the next step once I start feeling that even Sass is too repetitive for me.)


This meant that I needed to install those tools. I won’t go into the details of installing Sass: basically, you need Ruby + RubyGems, both of which I already had lying around, and both of which are entirely tangential to this series. (If you’re on a Mac and aren’t already a Ruby developer, then probably sudo gem install sass will do the trick.)

CoffeeScript, though, requires Node.js and npm, both of which I was going to need anyways and neither of which I had detailed experience with, so I’ll talk about them a bit more. On my Mac, I used Homebrew for both of those (if you install Node with Homebrew then npm comes along automatically); on my Linux server, I used the Ubuntu-packaged version of Node, and I installed npm following the standard instructions.

I initially did a global install of the coffee-script npm module. But you really want to control that sort of thing on a per-project level, so you can specify what version of a module you want: and npm lets you control that via a package.json file. There are lots of options that you can put in that file, and I imagine I’ll start using a lot more of them once I use npm to actually package up Medium, but for dependency management you can ignore almost all of the options. So here’s a sample package.json file if you just want to use it for dependency management:

  "name": "medium",
  "version": "0.0.0",
  "devDependencies": {
    "coffee-script": "^1.7.1"

Try putting that in a package.json file in an empty directory and then typing npm install. You’ll see that it installs coffee-script along with a package mkdirp that coffee-script depends on, and it puts them in a new subdirectory node_modules.

You can look at the docs for the version numbering if you want, but basically: ^1.7.1 means that it’s known to work with version 1.7.1, and later versions are probably okay. This is totally fine while I’m working on something for development; for a serious deployment, I’d probably want to pin things down more tightly, including specifying versions of packages pulled in indirectly.

One nice trick: say that you have new package that you want to start using. Then don’t bother looking up the version number and manually adding it to package.json: instead just do

npm install --save-dev NAME-OF-PACKAGE

That will look up the current version of that package, install it, and add an appropriate line to your package.json file. So that way you can start using the latest and greatest version of your package and get it working, and you’ve saved the information of what that version that worked for you was.

On which note: you of course want to check package.json into version control. For now, I’m putting node_modules in my .gitignore file; if I get to a situation where I’m serious about deployment, then I’ll want to have a way to get access to node_modules without depending on external sources for that, but even in that situation, storing it in the same git repository as the source code is the wrong approach (because of repository bloat). For a personal project just for fun, ignoring node_modules is totally acceptable.


So with that in place, I can compile CoffeeScript files by invoking node_modules/coffee-script/bin/coffee. Which is what I did initially, but I got a more formal build system in place fairly soon, I’ll talk about that next.

Post Revisions: