On Node.JS, Jade Templates, and Javascript Options Objects

Problem

I am currently building a project with node.js in Windows. I am using a batch file to assemble resources and build jade templates via the command line. With Jade, I am using the switch -o to defines a JS object that fills localized content in the template

For awhile, everything worked nicely. However, changes to my JSON lookup have resulted in an error: "The input line is too long"

Researching the error, I found that windows shell has a limit on how long your lines can be. Unfortunately, I need the whole lookup object for my project. However, I started wondering if jade can accept a path to my lookup file instead of a string with the contents of the file. Currently, I'm building the contents into a variable and calling jade with that ala:

SetLocal EnableDelayedExpansion
set content=
for /F "delims=" %%i in (%sourcedir%\assets\english.json) do set content=!content! %%i
::use the json file as a key for assembling the jade templates 
call jade %sourcedir% --out %destdir% -o"%content%"
EndLocal

If I could use a path to the lookup file, it would be much easier. However, I am usure how to do that (if it's even possible). and Jade's documentation is a bit lacking.

So, in short, is it possible for Jade to accept a filepath to a JS object rather than a string containing the object? Is there a better way to contruct the jade call that wont push it past the limit?

Problem courtesy of: user1026361

Solution

Write a node.js script that will read your "assets" and will call a jade. Something like:

var fs = require('fs'),
    _ = require('underscore'),
    async = require('async');

var sourceDir = 'path to the directory with your jade templates',
    destinationDir = 'path to the directory where you want the result html files to be contained in';

async.waterfall([
    async.parallel.bind(null, {
        serializedData: fs.readFile.bind(null, 'assets/english.json'),
        files: fs.readDir.bind(null, sourceDir),
    }),
    function (result, callback) {
        var data = JSON.parse(result.serializedData),
            files = result.files;
        async.parallel(_.map(files, function (file) {
            return async.waterfall.bind(null, [
                fs.readFile.bind(null, sourceDir + file),
                function (jadeSource, callback) {
                    process.nextTick(callback.bind(null, jade.compile(jadeSource)(data)));
                },
                fs.writeFile.bind(null, destinationDir + file)
            ]);
        }), callback);
    }
], function (err) {
    if (err) {
        console.log("An error occured: " + err);
    } else {
        console.log("Done!");
    }
});

Then in your batch file call this script directly, instead of enumerating the directory and calling the jade manually.

It will not only solve your problem, but also work much faster because:

  1. I/O operations are done in parallel;
  2. Node.js is only started once during the build process, as opposed to starting it for every single file as you do now.
Solution courtesy of: penartur

Discussion

There is currently no discussion for this recipe.

This recipe can be found in it's original form on Stack Over Flow.