Created
October 23, 2012 15:31
-
-
Save miguelludert/3939484 to your computer and use it in GitHub Desktop.
Less middleware for express
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var | |
fs = require("fs"), | |
__ = require("underscore"), | |
url = require('url'), | |
less = require('less'), | |
path = require('path'), | |
regex = /\.less$/, | |
cache = {}, | |
defaultOptions = { | |
src : "", | |
force : false, | |
compress : true | |
}, | |
options = {}, | |
send = function(pathname,res){ | |
res.set('Content-Type', 'text/css'); | |
res.send(cache[pathname].output); | |
}, | |
log = function(key, val, type) { | |
if(options.debug || type === 'error') { | |
switch(type) { | |
case 'log': | |
case 'info': | |
case 'error': | |
case 'warn': | |
break; | |
default: | |
type = 'log'; | |
} | |
console[type](' \033[90m%s :\033[0m \033[36m%s\033[0m', key, val); | |
} | |
}, | |
lessError = function(err,res,next) { | |
// create a user friendly error | |
var message = []; | |
message.push(err.message); | |
message.push("Line :" + err.line.toString()); | |
message.push("Index :" + err.index.toString()); | |
message.push("-------------------------------------------------------"); | |
__.each(err.extract,function(value){ | |
message.push(value); | |
}); | |
res.set('Content-Type', 'text/plain'); | |
res.send(message.join('\n')); | |
// log to the console | |
log("LESS " + err.type + ' error', err.message, 'error'); | |
log("LESS File", err.filename + ' ' + err.line + ':' + err.column, 'error'); | |
return next(err); | |
}, | |
error = function(err,next){ | |
return next('ENOENT' == err.code ? null : err); | |
}; | |
module.exports = function(custom_options){ | |
__.extend(options,defaultOptions,custom_options); | |
return function(req,res,next){ | |
if ('GET' != req.method.toUpperCase() && 'HEAD' != req.method.toUpperCase()) { return next(); } | |
var pathname = options.src + url.parse(req.url).pathname; | |
// if the file does not end in .less, leave the method. | |
if(!regex.test(pathname)){ | |
return next(); | |
} | |
// read file stats | |
fs.lstat(pathname,function(err,stats){ | |
if (err) { | |
return error(err,next); | |
} | |
// if it's already been cached, send it and leave; | |
if( !options.force && cache[pathname] && cache[pathname].mtime.getTime() == stats.mtime.getTime()){ | |
return send(pathname,res); | |
} | |
// if it's not been cached, read the file | |
fs.readFile(pathname,'utf8',function(err,str){ | |
if (err) { | |
return error(err,next); | |
} | |
var parser = new less.Parser({ | |
paths: [path.dirname(pathname)], | |
filename: pathname, | |
optimization: 0 | |
}); | |
// parse the contents | |
parser.parse(str, function(err, tree) { | |
if (err) { | |
return lessError(err,res,next); | |
} | |
var css = tree.toCSS({ | |
compress: options.compress, | |
yuicompress: false | |
}); | |
// cache the output | |
cache[pathname] = { | |
path : pathname, | |
output : css, | |
mtime : stats.mtime | |
}; | |
// send the output | |
return send(pathname,res); | |
}); | |
}); | |
}); | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment