Files
meteor/packages/less/plugin/compile-less.js
David Glasser ddc3657e4f Watch files which fail before emitting a resource
Regression introduced by the CSS watching code (specifically, f230eba62)
by the sourceIsWatched check. We need to be able to tell the difference
between "source handler didn't do anything because there was an error"
and "source handler didn't do anything because it's web-specific and
this is an os arch".

A simple fix would have been to interpret compileStep.error as
"sourceIsWatched = true", but I didn't think of that until after doing
it the slightly more complicated but more precise way :)

Also, ensure that if the runner rebuilds the client and there's an
error, it properly kills the app process (and the watchers and the
keepalive interval, etc).
2014-08-04 21:32:22 -07:00

66 lines
2.0 KiB
JavaScript

var fs = Npm.require('fs');
var path = Npm.require('path');
var less = Npm.require('less');
var Future = Npm.require('fibers/future');
Plugin.registerSourceHandler("less", {archMatching: 'web'}, function (compileStep) {
var source = compileStep.read().toString('utf8');
var options = {
filename: compileStep.inputPath,
// Use fs.readFileSync to process @imports. This is the bundler, so
// that's not going to cause concurrency issues, and it means that (a)
// we don't have to use Futures and (b) errors thrown by bugs in less
// actually get caught.
syncImport: true,
paths: [path.dirname(compileStep._fullInputPath)] // for @import
};
var parser = new less.Parser(options);
var astFuture = new Future;
var sourceMap = null;
try {
parser.parse(source, astFuture.resolver());
var ast = astFuture.wait();
var css = ast.toCSS({
sourceMap: true,
writeSourceMap: function (sm) {
sourceMap = JSON.parse(sm);
}
});
} catch (e) {
// less.Parser.parse is supposed to report any errors via its
// callback. But sometimes, it throws them instead. This is
// probably a bug in less. Be prepared for either behavior.
compileStep.error({
message: "Less compiler error: " + e.message,
sourcePath: e.filename || compileStep.inputPath,
line: e.line,
column: e.column + 1
});
return;
}
if (sourceMap) {
sourceMap.sources = [compileStep.inputPath];
sourceMap.sourcesContent = [source];
sourceMap = JSON.stringify(sourceMap);
}
compileStep.addStylesheet({
path: compileStep.inputPath + ".css",
data: css,
sourceMap: sourceMap
});
});;
// Register import.less files with the dependency watcher, without actually
// processing them. There is a similar rule in the stylus package.
Plugin.registerSourceHandler("import.less", function () {
// Do nothing
});
// Backward compatibility with Meteor 0.7
Plugin.registerSourceHandler("lessimport", function () {});