Skip to content

Instantly share code, notes, and snippets.

@etianen
Last active January 4, 2016 08:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save etianen/8595035 to your computer and use it in GitHub Desktop.
Save etianen/8595035 to your computer and use it in GitHub Desktop.
Optimizing LESS stylesheets with RequireJS
/**
* LESS stylesheet loader.
*
* Load a LESS stylesheet using style!main.less . This will load
* a stylesheet on the path ../css/main.less, compile it to CSS,
* and inject it in the page.
*
* During the optimization step with r.js, the stylesheet will be
* inlined with the javascript file.
*
* Takes one configuration variable, `cssRootUrl`, which should be
* an absolute URL to the location of the main CSS directory. This
* is needed to resolved relative image URLs in stylesheets. Either
* ensure that your image URLs are all absolute, or configure your
* stylesheet loader like:
*
* require.config({
* config: {
* style: {
* cssRootUrl: "/static/css/"
* }
* }
* });
*/
define([
"module",
"text"
], function(
module,
text
) {
var moduleConfig = module.config();
var buildMap = {};
var developmentParseConfig = {
env: "development"
};
var productionParseConfig = {
syncImport: true,
env: "production"
};
var productionOutputConfig = {
compress: true
};
function formatError(err) {
return new Error("LESS parse error in " + err.filename + " on line " + err.line + ", column " + err.column + ": " + err.message);
}
var style = {
_compile: function(less, url, parseConfig, outputConfig, onError, onSuccess) {
// Get the contents.
text.get(url, function(contents) {
// Create the parser.
parseConfig["filename"] = url;
parseConfig["paths"] = [moduleConfig.cssRootUrl];
parseConfig["rootpath"] = moduleConfig.cssRootUrl;
var parser = new (less.Parser)(parseConfig);
// Run the parser.
parser.parse(contents, function(err, tree) {
if (err) {
onError(formatError(err));
} else {
try {
var css = tree.toCSS(outputConfig);
onSuccess(css);
} catch(ex) {
onError(formatError(ex));
}
}
});
});
},
_injectCSS: function(css) {
var style = document.createElement("style");
style.appendChild(document.createTextNode(css));
document.head.appendChild(style);
},
load: function(name, parentRequire, onload, config) {
var url = require.toUrl("../css/" + name);
// How we act next depends on whether this is the browser.
if (config.isBuild) {
// This is an optimizing build
var less = require.nodeRequire("less");
style._compile(less, url, productionParseConfig, productionOutputConfig, onload.error, function(css) {
buildMap[name] = css;
onload(css);
});
} else {
// This is a browser session.
require(["less"], function(less) {
style._compile(less, url, {
env: "development"
}, developmentParseConfig, onload.error, function(css) {
style._injectCSS(css);
onload(css);
});
});
}
},
write: function (pluginName, moduleName, write) {
if (moduleName in buildMap) {
write("define('" + pluginName + "!" + moduleName + "', ['" + pluginName + "'], function (style) { return style._injectCSS('" + text.jsEscape(buildMap[moduleName]) + "');});\n");
}
}
};
return style;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment