Commit 5e7a7e68 by Andrew Nesbitt

Merge pull request #333 from nschonni/drop-middleware

Drop middleware and examples
parents 888ea82f 0bc7a085
/**
* Module dependencies.
*/
var connect = require('connect'),
sass = require('../sass');
// Setup server
// $ curl http://localhost:3000/test.css
var server = connect.createServer(
sass.middleware({
src: __dirname,
dest: __dirname + '/public',
debug: true,
outputStyle: 'compressed'
}),
connect.static(__dirname + '/public')
);
server.listen(3000);
console.log('server listening on port 3000');
*.css
\ No newline at end of file
#navbar {
width: 70%;
height: 23px; }
#navbar ul {
list-style-type: none; }
#navbar li {
float: left;
a {
font-weight: bold;
}
}
\ No newline at end of file
var sass = require('../sass'),
fs = require('fs'),
url = require('url'),
dirname = require('path').dirname,
mkdirp = require('mkdirp'),
join = require('path').join;
var imports = {};
/**
* Return Connect middleware with the given `options`.
*
* Options:
*
* `force` Always re-compile
* `debug` Output debugging information
* `src` Source directory used to find .scss files
* `dest` Destination directory used to output .css files
* when undefined defaults to `src`.
* `outputStyle` Sass output style (nested,expanded, compact or compressed)
*
* Examples:
*
* Pass the middleware to Connect, grabbing .scss files from this directory
* and saving .css files to _./public_.
*
* Following that we have a `staticProvider` layer setup to serve the .css
* files generated by Sass.
*
* var server = connect.createServer(
* sass.middleware({
* src: __dirname
* , dest: __dirname + '/public'
* })
* , connect.static(__dirname + '/public')
* );
*
* @param {Object} options
* @return {Function}
* @api public
*/
module.exports = function(options){
options = options || {};
// Accept src/dest dir
if ('string' === typeof options) {
options = { src: options };
}
// Force compilation
var force = options.force;
// Debug option
var debug = options.debug;
// Source dir required
var src = options.src;
if (!src) { throw new Error('sass.middleware() requires "src" directory'); }
// Default dest dir to source
var dest = options.dest
? options.dest
: src;
var root = options.root || null;
// Default compile callback
options.compile = options.compile || function(){
return sass;
};
// Middleware
return function sass(req, res, next){
if ('GET' !== req.method && 'HEAD' !== req.method) { return next(); }
var path = url.parse(req.url).pathname;
if (options.prefix && 0 === path.indexOf(options.prefix)) {
path = path.substring(options.prefix.length);
}
if (/\.css$/.test(path)) {
var cssPath = join(dest, path),
sassPath = join(src, path.replace('.css', '.scss')),
sassDir = dirname(sassPath);
if (root) {
cssPath = join(root, dest, path.replace(dest, ''));
sassPath = join(root, src, path
.replace(dest, '')
.replace('.css', '.scss'));
sassDir = dirname(sassPath);
}
if (debug) {
log('source', sassPath);
log('dest', cssPath);
}
// Ignore ENOENT to fall through as 404
var error = function(err) {
next('ENOENT' === err.code
? null
: err);
};
// Compile to cssPath
var compile = function() {
if (debug) { log('read', cssPath); }
fs.readFile(sassPath, 'utf8', function(err, str){
if (err) { return error(err); }
var style = options.compile();
var paths = [];
delete imports[sassPath];
style.render(str, function(err, css){
if (err) { return next(err); }
if (debug) { log('render', sassPath); }
imports[sassPath] = paths;
mkdirp(dirname(cssPath), 0700, function(err){
if (err) { return error(err); }
fs.writeFile(cssPath, css, 'utf8', next);
});
}, {
include_paths: [ sassDir ].concat(options.include_paths || options.includePaths || []),
image_path: options.image_path || options.imagePath,
output_style: options.output_style || options.outputStyle
});
});
};
// Force
if (force) { return compile(); }
// Re-compile on server restart, disregarding
// mtimes since we need to map imports
if (!imports[sassPath]) { return compile(); }
// Compare mtimes
fs.stat(sassPath, function(err, sassStats){
if (err) { return error(err); }
fs.stat(cssPath, function(err, cssStats){
// CSS has not been compiled, compile it!
if (err) {
if ('ENOENT' === err.code) {
if (debug) { log('not found', cssPath); }
compile();
} else {
next(err);
}
} else {
// Source has changed, compile it
if (sassStats.mtime > cssStats.mtime) {
if (debug) { log('modified', cssPath); }
compile();
// Already compiled, check imports
} else {
checkImports(sassPath, function(changed){
if (debug && changed && changed.length) {
changed.forEach(function(path) {
log('modified import %s', path);
});
}
changed && changed.length ? compile() : next();
});
}
}
});
});
} else {
next();
}
};
};
/**
* Check `path`'s imports to see if they have been altered.
*
* @param {String} path
* @param {Function} fn
* @api private
*/
function checkImports(path, fn) {
var nodes = imports[path];
if (!nodes) { return fn(); }
if (!nodes.length) { return fn(); }
var pending = nodes.length,
changed = [];
nodes.forEach(function(imported){
fs.stat(imported.path, function(err, stat){
// error or newer mtime
if (err || !imported.mtime || stat.mtime > imported.mtime) {
changed.push(imported.path);
}
--pending || fn(changed);
});
});
}
/**
* Log a message.
*
* @api private
*/
function log(key, val) {
console.error(' \033[90m%s :\033[0m \033[36m%s\033[0m', key, val);
}
......@@ -131,13 +131,13 @@ exports.renderSync = function(options) {
/**
Same as `render()` but with an extra `outFile` property in `options` and writes
the CSS and sourceMap (if requested) to the filesystem.
`options.sourceMap` can be used to specify that the source map should be saved:
- If falsy the source map will not be saved
- If `options.sourceMap === true` the source map will be saved to the
standard location of `options.file + '.map'`
- Else `options.sourceMap` specifies the path (relative to the `outFile`)
- Else `options.sourceMap` specifies the path (relative to the `outFile`)
where the source map should be saved
*/
exports.renderFile = function(options) {
......@@ -172,5 +172,3 @@ exports.renderFile = function(options) {
};
exports.render(options);
};
exports.middleware = require('./lib/middleware');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment