There is a beta version of 0.2.0 available. there will be several changes to the API so please test your code with the beta to discover any bugs before they become an issue. Also see the Migration Guide for what to expect and update.
If you are seeing an error about TypeError: Arguments to path.join must be strings
you have been upgraded to the beta version. You can either update your usage to match the updated API or change the prerequisite in your package.json
file to version ~0.1.15
to return to the stable version.
sudo npm install less-middleware
Option | Description | Default |
---|---|---|
force |
Always re-compile less files on each request. | false |
once |
Only check for need to recompile once after each server restart. Useful for reducing disk i/o on production. | false |
debug |
Output any debugging messages to the console. | false |
src |
Source directory containing the .less files. Required. |
|
dest |
Desitnation directory to output the compiled .css files. |
<src> |
paths |
Specify search paths for @import directives |
The dirname of <src> |
prefix |
Path which should be stripped from the public pathname . |
|
compress |
Compress the output being written to the *.css files. When set to 'auto' compression will only happen when the css file ends with .min.css or -min.css . |
auto |
yuicompress |
More involved minification with YUI compression | false |
optimization |
Desired level of LESS optimization. Optionally 0 , 1 , or 2 |
0 |
dumpLineNumbers |
Add line tracking to the compiled css. Optionally 0 , 'comments' , or 'mediaquery' |
0 |
relativeUrls |
Adjust urls to be relative to directory of files imported with @import. If false, urls will remain unchanged. | false |
sourceMap |
Enable sourcemap support. You can compile your less and then use developer tools to see where in your less file a particular piece of css comes from. | false |
preprocessor |
Specify a preprocessing function applied to LESS source code before parsing. The function will receive the LESS source code and the Connect request object as parameters, and must return the modified source code. | |
treeFunctions |
Object with custom functions added to less.tree.functions . |
var lessMiddleware = require('less-middleware');
var server = connect.createServer(
lessMiddleware({
src: __dirname + '/public',
compress: true
}),
connect.staticProvider(__dirname + '/public')
);
var lessMiddleware = require('less-middleware');
var app = express();
app.configure(function () {
// Other configuration here...
app.use(lessMiddleware({
src: __dirname + '/public',
compress: true
}));
app.use(express.static(__dirname + '/public'));
});
When using a different src
and dest
you can use the prefix
option to make the directory structure cleaner.
Requests for static assets (like stylesheets) made to the express server use a pathname
to look up the file. So if the request is for http://localhost/stylesheets/styles.css
the pathname
will be /stylesheets/styles.css
.
The less middleware uses that path to determine where to look for less files. In the original example it looks for the less file at /public/stylesheets/styles.less
and compiles it to /public/stylesheets/styles.css
.
If you are using a different src
and dest
options it causes for more complex directories structures unless you use the prefix
option. For example, without the prefix
, and with a src
of /src/less
and a dest
of /public
it would look for the less file at /src/less/stylesheets/styles.less
and compile it to /public/stylesheets/styles.css
. To make it cleaner you can use the prefix
option:
var lessMiddleware = require('less-middleware');
var app = express();
app.configure(function () {
// Other configuration here...
app.use(lessMiddleware({
dest: __dirname + '/public/stylesheets',
src: __dirname + '/src/less',
prefix: '/stylesheets',
compress: true
}));
app.use(express.static(__dirname + '/public'));
});
Using the prefix
it changes the pathname
from /stylesheets/styles.css
to /styles.css
. With that prefix removed from the pathname
it makes things cleaner. With the prefix
removed it would look for the less file at /src/less/styles.less
and compile it to /public/stylesheets/styles.css
.
A new alternative way to achieve the same thing as using prefix but with greater flexibility is to supply a shared root value. From this shared root, you would specify a URI style path to the appropriate source and destination directories:
var lessMiddleware = require('less-middleware')
, path = require('path')
, pubDir = path.join(__dirname, 'public')
, app = express();
app.configure(function() {
app.use(lessMiddleware({
dest: '/css', // should be the URI to your css directory from the location bar in your browser
src: '/less', // or '../less' if the less directory is outside of /public
root: pubDir,
compress: true
}));
app.use(express.static(pubDir));
});
This will allow any file under the /less directory, including subdirectories, to be compiled into an identical directory structure under /css.
Since less middleware relies on static content to be served by express.static, using temp directories just requires that you inform express about where generated files are built:
var lessMiddleware = require('less-middleware'),
os = require('os');
var app = express();
app.configure(function () {
// Other configuration here...
var tmpDir = path.join(os.tmpDir(), 'css-cache');
app.use(lessMiddleware({
src: __dirname + '/public/stylesheets',
dest: tmpDir,
compress: true
}));
app.use(express.static(__dirname + '/public'));
app.use(express.static(tmpDir));
});
Using a temp directory is useful for read-only file systems, such as a Heroku deployment. By using a temp directory the css files can still be written and served.
By default the directory in which the compiled files live in is already set as an import directive:
// file1.less
@import 'file2.less';
body {
color: @bodyColor;
}
// file2.less
@bodyColor: #333333;
However, you can use the paths
option if you need to specify other directories in which to search for importable less files.
var less = require('less-middleware'),
path = require('path');
lessMiddleware({
src: path.join(__dirname, 'public'),
paths: [path.join(__dirname, 'module', 'less')]
});
// public/base.css
@import 'colors';
body {
color: @bodyColor;
}
// module/less/colors.less
@bodyColor: #333333;
Here's an example on how to use Twitter's bootstrap within an Express.js set-up:
// package.json
{
"name": "my-module",
// ...
"dependencies": {
"less-middleware": "*",
"bootstrap": "git+https://github.com/twitter/bootstrap.git#v2.2.2",
"express": "3.0"
}
}
// app.js
var express = require('express')
, path = require('path')
, app = express()
, less = require('less-middleware');
app.configure(function(){
// ...
var bootstrapPath = path.join(__dirname, 'node_modules', 'bootstrap');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use('/img', express['static'](path.join(bootstrapPath, 'img')));
app.use(app.router);
app.use(less({
src : path.join(__dirname, 'assets', 'less'),
paths : [path.join(bootstrapPath, 'less')],
dest : path.join(__dirname, 'public', 'stylesheets'),
prefix : '/stylesheets'
}));
app.use(express['static'](path.join(__dirname, 'public')));
// ...
});
// ...
// assets/less/base.less
@import 'bootstrap';
@import 'responsive';
@bodyBackground: #FAF7EC;
@navbarBrandColor: #989CAE;
.brand {
font-family: @monoFontFamily;
}
var lessMiddleware = require('less-middleware');
var app = express();
app.configure(function () {
// Other configuration here...
app.use(lessMiddleware({
src: __dirname + '/public',
preprocessor: function(src, req) {
if (req.param("namespace")) {
src = req.param("namespace") + " { " + src + " }";
}
return src;
},
compress: true
}));
app.use(express.static(__dirname + '/public'));
});
Make sure you're declaring less-middleware before your static middleware, if you're using the same directory, e.g. (with express):
app.use(require('less-middleware')({ src: __dirname + '/public', debug: true }));
app.use(express.static(path.join(__dirname, 'public')));
not
app.use(express.static(path.join(__dirname, 'public')));
app.use(require('less-middleware')({ src: __dirname + '/public', debug: true }));
If you are hosting your app on IIS you will have to modify your web.config
file in order to allow NodeJS to serve your CSS static files. IIS will cache your CSS files, bypassing NodeJS static file serving, which in turn does not allow the middleware to recompile your LESS files.