diff --git a/lib/less/import-manager.js b/lib/less/import-manager.js index 79d2f3fec..8c6460a21 100644 --- a/lib/less/import-manager.js +++ b/lib/less/import-manager.js @@ -109,9 +109,21 @@ module.exports = function(environment) { } else if (importOptions.inline) { fileParsedFunc(null, contents, resolvedFilename); } else { - new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) { - fileParsedFunc(e, root, resolvedFilename); - }); + var importsCache = require('./imports-cache'); + var entry = importsCache.get(resolvedFilename); + if (entry && entry.root) { + fileParsedFunc(null, entry.root, resolvedFilename); + } + else { + new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) { + + importsCache.set(resolvedFilename, { + contents: contents, + root: root + }); + fileParsedFunc(e, root, resolvedFilename); + }); + } } }; diff --git a/lib/less/imports-cache.js b/lib/less/imports-cache.js new file mode 100644 index 000000000..a2773ff4f --- /dev/null +++ b/lib/less/imports-cache.js @@ -0,0 +1,36 @@ + + +// When the cache is disabled, it will stay empty + +var cache = {}; +var enabled = false; + +module.exports = { + + isEnabled: function() { + return enabled; + }, + enable: function() { + enabled = true; + }, + disable: function() { + enabled = false; + this.clean(); + }, + + set: function (key, value) { + if ( enabled ) { + cache[key] = value; + } + }, + get: function (key) { + return cache[key]; + }, + remove: function(key) { + delete cache[key]; + }, + clean: function(key) { + cache = {}; + } +}; + diff --git a/lib/less/index.js b/lib/less/index.js index 2e24061e9..6b3fbdbf2 100644 --- a/lib/less/index.js +++ b/lib/less/index.js @@ -17,6 +17,7 @@ module.exports = function(environment, fileManagers) { ParseTree: (ParseTree = require('./parse-tree')(SourceMapBuilder)), ImportManager: (ImportManager = require('./import-manager')(environment)), render: require("./render")(environment, ParseTree, ImportManager), + invalidateImportsCacheFile: require("./imports-cache").remove, parse: require("./parse")(environment, ParseTree, ImportManager), LessError: require('./less-error'), transformTree: require('./transform-tree'), diff --git a/lib/less/render.js b/lib/less/render.js index 95a191dd4..8be4c4ba0 100644 --- a/lib/less/render.js +++ b/lib/less/render.js @@ -1,5 +1,9 @@ var PromiseConstructor; +var importsCache = require('./imports-cache'); + + + module.exports = function(environment, ParseTree, ImportManager) { var render = function (input, options, callback) { if (typeof options === 'function') { @@ -7,6 +11,20 @@ module.exports = function(environment, ParseTree, ImportManager) { options = {}; } + // importsCache can be enabled or disabled per render phase + if ( options.withImportsCaching ) { + importsCache.enable(); + // If you invalidate cache yourself, you will have to call + // less.invalidateImportsCacheFile(filePath) everytime a less file is modified + if ( !options.withManualImportsCachingInvalidation ) { + importsCache.clean(); + } + } + else { + importsCache.disable(); + } + + if (!callback) { if (!PromiseConstructor) { PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise;