Last active
January 4, 2016 08:19
-
-
Save etianen/8595035 to your computer and use it in GitHub Desktop.
Optimizing LESS stylesheets with RequireJS
This file contains 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
/** | |
* 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