Last Updated: September 09, 2019
·
8.945K
· jiewmeng

Precompile jade templates with NodeJS/Express for use on client side

A simple Node module exporting a single function compile

fs = require "fs"
jade = require "jade"
async = require "async"

# done callback will be passed (source, err)
exports.compile = (done, templatesDir) ->
    js = "var Templates = {}; \n\n"

    # get all files in templates directory
    fs.readdir templatesDir, (err, files) ->
        # keep only ".jade" files
        jadeFiles = files.filter (file) -> 
            file.substr(-5) == ".jade"

        # function to compile jade templates (appending to js source)
        compileTmpl = (file, doneCompile) ->
            # "test.jade" becomes "test"
            key = file.substr(0, file.indexOf("."))
            filePath = templatesDir + file
            fs.readFile filePath, (err, src) ->
                # store js function source into Templates.{key}
                js += "Templates." + key + " = " + jade.compile(src, { debug: false, client: true }).toString() + "; \n\n"
                doneCompile(err)

        # foreach jadeFile, compile template, then write templates.js file
        async.forEach jadeFiles, compileTmpl, (err) ->
            done(js, err)

It accepts 2 parameters: a done callback which is passed the JS source of the precompiled templates; and a templatesDir specifying the location of the Jade templates to be compiled.

It reads all jade files in templates directory, compiling each template for use in client side with jade.compile(tmpl, {client: true, debug: false}) into Templates.key where key is the filename without extension. Meaning, ExampleView.jade will be compiled into Templates.ExampleView. Then used like:

  • Templates.ExampleView()
  • or Templates.ExampleView({ title: "Some title" })

Example usage with ExpressJS

require("coffee-script");
var jadePrecompiler = require("./jadePrecompiler.coffee"),
    precompiledTemplatesSource = "",
    doneCompile = function(source, err) {
      if (err) { throw err; } 
      precompiledTemplatesSource = source;
    };
jadePrecompiler.compile(doneCompile, "../client/templates/");

app.get("/js/templates.js", function(req, res) {
  res.set("Content-Type", "application/javascript");
  res.send(precompiledTemplatesSource);
});

Then on client side, include the jade runtime.js, include your template, then use them like: Templates.something(locals)

Here to simplify things, I did not consider the case where jadePrecompiler.compile is not completed when request to /js/templates.js is made.

An example on JS Fiddle: http://jsfiddle.net/qjDKH/

3 Responses
Add your response

Great stuff!

over 1 year ago ·

@willmo36 Thanks :)

over 1 year ago ·

Yeah this is super useful!

over 1 year ago ·