Don McCurdy Software Developer in Cambridge, MA.

Hi — I’m a developer at Google, currently working on Project Sunroof.

I love web development, design, and tools for understanding and visualizing data. Solutions for humanitarian and environmental issues are important to me. Let’s build something.

Recent Posts

NPM Version Bumping and Extra Files

NPM has a handy little feature for bumping the versions on your packages, and it works like this:

npm version [major | minor | patch]

Want to run tests first, minify your code, and only publish the new version if everything works? Sure:

// package.json
{

  ...

  "scripts": {
    "preversion": "npm test",
    "version": "npm run dist && git add -A dist",
    "postversion": "git push && git push --tags && npm publish"
  }
}

Ok, but what if the package has a bower.json, too? Or if other files need to include the current version number? Gulp and Grunt both have plugins to automate this, but NPM scripts don’t.

In my case, I wanted to include a RawGit CDN link in my README, and have it always include the latest stable version. Here’s what I did:

npm install --save-dev replace
// package.json
{

  ...

  "scripts": {
    "preversion": "npm test",
    "preversion:readme": "replace '/v\\d+\\.\\d+\\.\\d+' \"/v$npm_package_version\" ./README.md",
    "version": "npm run preversion:readme && npm run dist && git add -A dist README.md",
    "postversion": "git push && git push --tags && npm publish"
  }
}

With those four tasks, npm version patch will now:

  1. Run your tests, and abort if they fail.
  2. Build your dist/ scripts.
  3. Bump the version in package.json.
  4. Bump the version in README.md.
  5. Commit package.json, README.md, and the dist/ output.
  6. Create a new tag.
  7. Push the commit and tag to GitHub.
  8. Publish the new version on NPM.

For more on how this works, see the full documentation on NPM scripts.

What Can a Technologist Do About Climate Change

From an essay by Bret Victor (@worrydream), on how the tech community “can contribute to tech and/or policy solutions,” and why this is important —

You cannot calibrate your sense of what’s valuable and necessary to the current fashions in your field.

Climate change is the problem of our time. It’s everyone’s problem, but it’s our responsibility — as people with the incomparable leverage of being able to work magic through technology.

Read the full essay here. It’s excellent. I don’t mean to say that there aren’t other problems worth your time, but the general state of the tech community suggests we don’t value our time or energy highly enough.

Using ES6 Generators with Callback-based Libraries

ES6 introduces generators (and yield expressions) to JavaScript. Kyle Simpson has written a nice introduction to generators, if you’re looking for more about how they work.

They’re a very welcome change from callbacks-of-infinite-sorrow situations, but generators aren’t necessarily well supported by most NPM packages. Which raises the question:

How do I use generators with callback-based libraries and older code?

I ran into this problem while trying out Koa (web framework, generators everywhere) and node-sqlite3 (database bindings with callbacks). Some NPM packages do come with generator support, but these are harder to find – and less likely to be stable – for a while yet. Let’s take some older code relying on callbacks and wire it up with a generator.

Here’s a basic fetch-things-from-a-database example:

var db = new ArbitraryDB();

var gizmoService = {
    /**
     * List all Gizmos.
     */
    all: function () {
        db.all(function (error, result) {
            // [1] ???
        });
        // [2] ???
    }
};

// Application code.
// Let's protect this part from nasty callbacks.
var gizmos = gizmoService.all();
console.log(gizmos); // NULL

Well, that doesn’t work. We need to return a value at [2], but the callback at [1] hasn’t been invoked yet. Native Promises (not polyfills, unfortunately) can solve this problem.

NOTE: As of this writing, generators in NodeJS only work with the --harmony flag. I’m using NPM v0.12.0.

An updated example:

var db = new ArbitraryDB();

var gizmoService = {
    /**
     * List all Gizmos.
     */
    all: function *() {
        // Return a new Promise
        return new Promise(function(resolve, reject) {
            db.all(function (error, result) {
                // ... and resolve or reject with the result.
                if (error) {
                    reject(error);
                } else {
                    resolve(result);
                }
            });
        });
    }
};

// Application code.
var gizmos = yield gizmoService.all();
console.log(gizmos); // [ ... gizmos ... ]

Or, to catch possible DB-level errors:

try {
    var gizmos = yield gizmoService.getAll();
} catch (error) {
    console.log('Oh, it broke.');
}

And that’s it! The rest of your application can continue without worrying about the callbacks tucked away in a dependency.