Installing node-canvas on Windows

There’s an article here that describes the process, but it’s a bit vague in some areas and didn’t work for me.

If you’re on 64-bit Windows, you will need the 64-bit version of GTK which comes bundled with Cairo if you get the all-in-one package. Somewhere under the mile of text on this page you should find a link to it; here’s a direct link for version 2.22.

It’s a zip. Extract it to c:/GTK. I don’t even what to consider what’s involved making it work from a different location.

You also need node-gyp. Install it via

npm install -g node-gyp

Once you’ve got all the dependencies you can attempt to install node-canvas. “CD” into your project directory and then run

npm install canvas --msvs_version=2012

Adjust the version number for whatever version of Visual Studio you have. The Wiki says to use VC++ 2010 Express which is also a bitch to find on Microsoft’s website as they push you towards 2013. Here’s a direct link which may or not work.

Even after installing VS2010 though, npm/gyp wouldn’t pick it up automatically, which is why I had to specify the version manually. Even then 2010 didn’t work, but 2012 did, so, whatever.

If you get some linker errors, you probably have an old version of Cairo.

If you get something about cairo-features, it’s probably the same deal. Those can be fixed by opening the .sln in Visual Studio and updating the include dirs to include C:/GTK/includes/cairo, but then you’ll be left with a new error, and they’ll probably never end, so just try different versions of the GTK bundle until you find one that works. Maybe try 32-bit if the 64-bit one doesn’t work for you (32 didn’t work for me).

Compile all Jade files to a single client-side JavaScript file

Jade is “a high performance template engine heavily influenced by Haml and implemented with JavaScript for node”.

One of it’s nice features is that it lets you compile your Jade templates into JavaScript functions which can be ran client-side. This is particularly useful when you want to pass JSON data back from an AJAX call and render it; it keeps you have from having to pass HTML “over the wire” or from writing complex JavaScript to rebuild your DOM elements. It’s also super fast.

After installing Jade, you can compile a single template via the command-line by running jade -c template.jade. This will generate a *.js file that looks like this:

function anonymous(locals, attrs, escape, rethrow, merge) {
    ...
}

Which is great, except that it’s just about unusable as-is. If you try including that to your page, you now have access to a single function called “anonymous” — not very helpful. The problem gets worse if you want to have access to more than one template.

Wouldn’t it be nicer if all of your templates got compiled to a single object with a sensible name, which you could use the access all your template functions? That’s why I wrote a script to compile all your Jade files into a single .js file that looks like this:

var Templates = {
"login":
  function anonymous(locals, attrs, escape, rethrow, merge) {
      ..
  },
"change_password":
  function anonymous(locals, attrs, escape, rethrow, merge) {
      ..
  }
};

Now you just need to include that Jade runtime plus this file that got generated via:

<script type="text/javascript" src="/js/jade/runtime.js"></script>
<script type="text/javascript" src="/js/templates.js"></script>

You can find runtime.js inside node_modules/jade after you install it.

Here’s the script:

var Jade = require('jade');
var FileSystem = require('fs');
var Path = require('path');
var _ = require('underscore');

var outName = 'public/js/templates.js';
var viewsDir = 'views';

files = FileSystem.readdirSync(viewsDir);
var templates = {};
files.forEach(function(filename) {
    if(/\.jade$/.test(filename)) {
        var name = Path.basename(filename, '.jade');
        var path = Path.join(viewsDir, filename);
        console.log('compiling', path);
        var fileContents = FileSystem.readFileSync(path, {encoding: 'utf8'});
        templates[name] = Jade.compile(fileContents, {
            debug: false,
            compileDebug: true,
            filename: path,
            client: true
        });
    }
});
console.log('writing', outName);

var properties = [];
_.each(templates, function(value, key) {
    properties.push(JSON.stringify(key) + ':\n  ' + value.toString());
});
var sourceCode = 'var Templates = {\n' + properties.join(',\n\n') + '\n};';

FileSystem.writeFile(outName, sourceCode);

I called mine “compile_jade.js”. You run it via “node compile_jade.js”. You will probably need to adjust your paths as necessary (see “outName” and “viewsDir” near the top). I will probably expand on this script in the future, but this should be enough to get you started with client-side Jade!

If you’re using PhpStorm or WebStorm like me, you can set up a File Watcher to watch your Jade files have it automatically re-run this script whenever you edit one of them:

jade-compiler