less-middleware
Advanced tools
Comparing version 1.0.4 to 2.0.0
@@ -10,3 +10,2 @@ "use strict"; | ||
var determine_imports = require('./determine-imports'); | ||
var extend = require('node.extend'); | ||
@@ -22,3 +21,2 @@ var fs = require('fs'); | ||
var lessFiles = {}; | ||
var cachedLessFiles = {}; | ||
var cacheFileInitialized = false; | ||
@@ -51,3 +49,3 @@ // Allow tests to force flushing of cacheFile | ||
var loadCacheFile = function(cacheFile, log) { | ||
var initCacheFile = function(cacheFile, log) { | ||
cacheFileInitialized = true; | ||
@@ -82,3 +80,3 @@ var cacheFileSaved = false; | ||
try { | ||
extend(cachedLessFiles, JSON.parse(data)); | ||
lessFiles = extend(JSON.parse(data), lessFiles); | ||
} catch (err) { | ||
@@ -96,8 +94,3 @@ log('error parsing cached imports in file ' + cacheFile, err); | ||
*/ | ||
module.exports = less.middleware = function(source, options, parserOptions, compilerOptions){ | ||
// Check for 0.1.x usage. | ||
if (typeof source == 'object') { | ||
throw new Error('Please update your less-middleware usage: http://goo.gl/aXuck7'); | ||
} | ||
module.exports = less.middleware = function(source, options){ | ||
// Source dir is required. | ||
@@ -110,7 +103,3 @@ if (!source) { | ||
options = extend(true, { | ||
compiler: extend(true, { | ||
compress: 'auto', | ||
sourceMap: false, | ||
yuicompress: false | ||
}, compilerOptions || {}), | ||
cacheFile: null, | ||
debug: false, | ||
@@ -120,12 +109,6 @@ dest: source, | ||
once: false, | ||
parser: extend(true, { | ||
dumpLineNumbers: 0, | ||
paths: [source], | ||
optimization: 0, | ||
relativeUrls: false | ||
}, parserOptions || {}), | ||
pathRoot: null, | ||
cacheFile: null, | ||
postprocess: { | ||
css: function(css, req) { return css; } | ||
css: function(css, req) { return css; }, | ||
sourcemap: function(sourcemap, req) { return sourcemap; } | ||
}, | ||
@@ -136,3 +119,7 @@ preprocess: { | ||
}, | ||
storeCss: function(pathname, css, next) { | ||
render: { | ||
compress: 'auto', | ||
yuicompress: false | ||
}, | ||
storeCss: function(pathname, css, req, next) { | ||
mkdirp(path.dirname(pathname), 511 /* 0777 */, function(err){ | ||
@@ -143,2 +130,12 @@ if (err) return next(err); | ||
}); | ||
}, | ||
storeSourcemap: function(pathname, sourcemap, req) { | ||
mkdirp(path.dirname(pathname), 511 /* 0777 */, function(err){ | ||
if (err) { | ||
utilities.lessError(err); | ||
return; | ||
} | ||
fs.writeFile(pathname, sourcemap, 'utf8'); | ||
}); | ||
} | ||
@@ -150,61 +147,9 @@ }, options || {}); | ||
// Deprecate the usage of separate options. | ||
if(typeof parserOptions != 'undefined' || typeof compilerOptions != 'undefined') { | ||
log('deprecated', 'Use of the separate arguments for parser and compiler options is deprecated'); | ||
if (options.cacheFile && !cacheFileInitialized) { | ||
initCacheFile(options.cacheFile, log); | ||
} | ||
if (options.cacheFile && !cacheFileInitialized) { | ||
loadCacheFile(options.cacheFile, log); | ||
} | ||
// Expose for testing. | ||
less.middleware._saveCacheToFile = _saveCacheToFile; | ||
// Parse and compile the CSS from the source string. | ||
var render = function(str, lessPath, cssPath, callback) { | ||
var parser = new less.Parser(extend({}, options.parser, { | ||
filename: lessPath | ||
})); | ||
parser.parse(str, function(err, tree) { | ||
if(err) { | ||
return callback(err); | ||
} | ||
try { | ||
// If sourceMap is enabled, set sourceMapbasepath to the directory of the less file | ||
// Set sourceMapURL to enable separate source-map file. | ||
if( options.compiler.sourceMap ){ | ||
options.compiler.sourceMapBasepath = path.dirname( lessPath ); | ||
options.compiler.sourceMapURL = path.basename( lessPath, '.less' ) + '.css.map'; | ||
// To generate the exact source-map file. | ||
options.compiler.writeSourceMap = function( sourceMap ){ | ||
var sourceMapFilePath = path.join( path.dirname( cssPath ), path.basename( cssPath, '.css' ) + '.css.map' ); | ||
fs.writeFile( sourceMapFilePath, sourceMap, function( err ){ | ||
if( err ){ | ||
log( 'source-map', 'write source map to ' + sourceMapFilePath + ' fail, error: ', err ); | ||
} | ||
else { | ||
log( 'source-map', 'Write source map to ' + sourceMapFilePath + ' success.' ); | ||
} | ||
}); | ||
}; | ||
} | ||
var css = tree.toCSS(extend({}, options.compiler, { | ||
compress: (options.compress == 'auto' ? utilities.isCompressedPath(cssPath) : options.compress) | ||
})); | ||
// Store the less import paths for cache invalidation. | ||
lessFiles[lessPath] = { | ||
mtime: Date.now(), | ||
imports: determine_imports(tree, lessPath, options.parser.paths) | ||
}; | ||
callback(err, css); | ||
} catch(parseError) { | ||
callback(parseError, null); | ||
} | ||
}); | ||
}; | ||
// Actual middleware. | ||
@@ -233,2 +178,4 @@ return function(req, res, next) { | ||
var sourcemapPath = cssPath + '.map'; | ||
// Allow for preprocessing the source filename. | ||
@@ -256,3 +203,4 @@ lessPath = options.preprocess.path(lessPath, req); | ||
lessSrc = options.preprocess.less(lessSrc, req); | ||
render(lessSrc, lessPath, cssPath, function(err, css){ | ||
options.render.filename = lessPath; | ||
less.render(lessSrc, options.render, function(err, output){ | ||
if (err) { | ||
@@ -263,7 +211,21 @@ utilities.lessError(err); | ||
// Allow postprocessing on the css. | ||
css = options.postprocess.css(css, req); | ||
// Store the less paths for simple cache invalidation. | ||
lessFiles[lessPath] = { | ||
mtime: Date.now(), | ||
imports: output.imports | ||
}; | ||
// Allow postprocessing for custom storage. | ||
options.storeCss(cssPath, css, next); | ||
if(output.map) { | ||
// Postprocessing on the sourcemap. | ||
var map = options.postprocess.sourcemap(output.map, req); | ||
// Custom sourcemap storage. | ||
options.storeSourcemap(sourcemapPath, map, req); | ||
} | ||
// Postprocessing on the css. | ||
var css = options.postprocess.css(output.css, req); | ||
// Custom css storage. | ||
options.storeCss(cssPath, css, req, next); | ||
}); | ||
@@ -289,7 +251,3 @@ } catch (err) { | ||
if (!lessFiles[lessPath]) { | ||
if (cachedLessFiles[lessPath]) { | ||
lessFiles[lessPath] = cachedLessFiles[lessPath]; | ||
} else { | ||
return compile(); | ||
} | ||
return compile(); | ||
} | ||
@@ -311,6 +269,8 @@ | ||
return compile(); | ||
} else { | ||
return next(err); | ||
} | ||
} else if (lessStats.mtime > cssStats.mtime) { | ||
return next(err); | ||
} | ||
if (lessStats.mtime > cssStats.mtime) { | ||
// Source has changed, compile it | ||
@@ -322,3 +282,3 @@ log('modified', cssPath); | ||
// This can happen if lessFiles[lessPath] was copied from | ||
// cachedLessFiles above, but the cache file was out of date (which | ||
// cacheFile above, but the cache file was out of date (which | ||
// can happen e.g. if node is killed and we were unable to write out | ||
@@ -325,0 +285,0 @@ // lessFiles on exit). Since imports might have changed, we need to |
@@ -5,3 +5,3 @@ { | ||
"description": "LESS.js middleware for connect.", | ||
"version": "1.0.4", | ||
"version": "2.0.0", | ||
"repository": { | ||
@@ -13,11 +13,11 @@ "type": "git", | ||
"dependencies": { | ||
"less": "1.7.x", | ||
"mkdirp": "~0.3.5", | ||
"node.extend": "~1.0.8" | ||
"less": "2.4.x", | ||
"mkdirp": "~0.5", | ||
"node.extend": "~1.1" | ||
}, | ||
"devDependencies": { | ||
"mocha": "~1.17.1", | ||
"supertest": "~0.9.0", | ||
"express": "~3.4.7", | ||
"fs-extra": "~0.11.0" | ||
"mocha": "~2.1", | ||
"supertest": "~0.15", | ||
"express": "~4.11", | ||
"fs-extra": "~0.16" | ||
}, | ||
@@ -24,0 +24,0 @@ "engines": { |
{ | ||
"{$}/import.less":{ | ||
"imports":[ | ||
{ | ||
"path":"{$}/import-header.less" | ||
}, | ||
{ | ||
"path":"{$}/import-color.less" | ||
}, | ||
{ | ||
"path":"{$}/import-widget.less" | ||
} | ||
"{$}/import.less": { | ||
"imports": [ | ||
"{$}/import-header.less", | ||
"{$}/import-widget.less", | ||
"{$}/import-color.less" | ||
] | ||
} | ||
} |
{ | ||
"{$}/import.less":{ | ||
"imports":[ | ||
{ | ||
"path":"{$}/import-color.less" | ||
} | ||
"{$}/import.less": { | ||
"imports": [ | ||
"{$}/import-color.less" | ||
] | ||
} | ||
} | ||
} |
@@ -50,4 +50,6 @@ "use strict"; | ||
force: true, // Need to force since using the same file as the simple test. | ||
compiler: { | ||
sourceMap: true | ||
render: { | ||
sourceMap: { | ||
sourceMapBasepath: __dirname + '/fixtures' | ||
} | ||
} | ||
@@ -115,4 +117,4 @@ }); | ||
less: function(src, req) { | ||
if (req.param("namespace")) { | ||
src = req.param("namespace") + " { " + src + " }"; | ||
if (req.query.namespace) { | ||
src = req.query.namespace + " { " + src + " }"; | ||
} | ||
@@ -185,72 +187,79 @@ return src; | ||
}); | ||
}); | ||
describe('cacheFile', function() { | ||
var middlewareSrc = tmpDest + '/fixturesCopy'; | ||
var dest = tmpDest + '/cacheFileTest'; | ||
var cacheFile = dest + '/cacheFile.json'; | ||
try { | ||
mkdirp.sync(middlewareSrc); | ||
} catch(e) { | ||
if (e && e.code != 'EEXIST') throw e; | ||
} | ||
copySync(__dirname + '/fixtures', middlewareSrc); | ||
var app; | ||
var expandExpected = function(file) { | ||
return file.replace(/\{\$\}/g, middlewareSrc); | ||
} | ||
describe('cacheFile', function() { | ||
var middlewareSrc = tmpDest + '/fixturesCopy'; | ||
var dest = tmpDest + '/cacheFileTest'; | ||
var cacheFile = dest + '/cacheFile.json'; | ||
try { | ||
mkdirp.sync(middlewareSrc); | ||
} catch(e) { | ||
if (e && e.code != 'EEXIST') throw e; | ||
} | ||
copySync(__dirname + '/fixtures', middlewareSrc); | ||
var app; | ||
var checkCacheFile = function(cacheFile, expectedFile){ | ||
return function(){ | ||
middleware._saveCacheToFile(); | ||
var cacheFileExpected = JSON.parse(expandExpected(fs.readFileSync(expectedFile, 'utf8'))); | ||
var cacheFileOutput = JSON.parse(fs.readFileSync(cacheFile, 'utf8')); | ||
for (var file in cacheFileExpected) { | ||
assert(cacheFileOutput[file] != undefined); | ||
var expectedImports = cacheFileExpected[file].imports; | ||
var outputImports = cacheFileOutput[file].imports; | ||
for (var i = 0; i < expectedImports.length; i++) { | ||
assert.equal(expectedImports[i].path, outputImports[i].path); | ||
} | ||
assert.equal(outputImports.length, expectedImports.length); | ||
var expandExpected = function(file) { | ||
return file.replace(/\{\$\}/g, middlewareSrc); | ||
} | ||
var checkCacheFile = function(cacheFile, expectedFile){ | ||
return function(){ | ||
// Force cacheFile write. | ||
middleware._saveCacheToFile(); | ||
var cacheFileExpected = JSON.parse(expandExpected(fs.readFileSync(expectedFile, 'utf8'))); | ||
var cacheFileOutput = JSON.parse(fs.readFileSync(cacheFile, 'utf8')); | ||
for (var file in cacheFileExpected) { | ||
assert(cacheFileOutput[file] != undefined); | ||
var expectedImports = cacheFileExpected[file].imports.sort(); | ||
var outputImports = cacheFileOutput[file].imports.sort(); | ||
assert.equal(outputImports.length, expectedImports.length); | ||
for (var i = 0; i < expectedImports.length; i++) { | ||
assert.equal(expectedImports[i], outputImports[i]); | ||
} | ||
} | ||
} | ||
} | ||
beforeEach(function() { | ||
// Unfortunately because cache-related items are stored in globals | ||
// (which they need to be so that they are shared across different | ||
// middleware invocations), to properly test the cacheFile option we | ||
// need to re-require the middleware for each of these tests. | ||
var mpath = path.resolve(__dirname, '../lib/middleware.js'); | ||
delete require.cache[mpath]; | ||
middleware = require('../lib/middleware'); | ||
app = setupExpress(middlewareSrc, { | ||
dest: dest, | ||
cacheFile: cacheFile | ||
}); | ||
beforeEach(function() { | ||
// Unfortunately because cache-related items are stored in globals | ||
// (which they need to be so that they are shared across different | ||
// middleware invocations), to properly test the cacheFile option we | ||
// need to re-require the middleware for each of these tests. | ||
var mpath = path.resolve(__dirname, '../lib/middleware.js'); | ||
delete require.cache[mpath]; | ||
middleware = require('../lib/middleware'); | ||
app = setupExpress(middlewareSrc, { | ||
dest: dest, | ||
cacheFile: cacheFile | ||
}); | ||
}); | ||
it('should process files correctly and store the right cached imports', function(done){ | ||
var expected = fs.readFileSync(__dirname + '/fixtures/import-exp.css', 'utf8'); | ||
request(app) | ||
.get('/import.css') | ||
.expect(200) | ||
.expect(expected) | ||
.expect(checkCacheFile(cacheFile, __dirname + '/fixtures/cacheFile-exp.json')) | ||
.end(done); | ||
}); | ||
it('should process files correctly and store the right cached imports', function(done){ | ||
var expected = fs.readFileSync(__dirname + '/fixtures/import-exp.css', 'utf8'); | ||
request(app) | ||
.get('/import.css') | ||
.expect(200) | ||
.expect(expected) | ||
.expect(checkCacheFile(cacheFile, __dirname + '/fixtures/cacheFile-exp.json')) | ||
.end(done); | ||
}); | ||
it('should ignore cached imports if the file has changed and update cached imports', function(done){ | ||
copySync(middlewareSrc + '/importSimple.less', middlewareSrc + '/import.less'); | ||
var expected = fs.readFileSync(__dirname + '/fixtures/importSimple-exp.css', 'utf8'); | ||
request(app) | ||
.get('/import.css') | ||
.expect(200) | ||
.expect(expected) | ||
.expect(checkCacheFile(cacheFile, __dirname + '/fixtures/cacheFile-exp2.json')) | ||
.end(done); | ||
}); | ||
it('should ignore cached imports if the file has changed and update cached imports', function(done){ | ||
copySync(middlewareSrc + '/importSimple.less', middlewareSrc + '/import.less'); | ||
var expected = fs.readFileSync(__dirname + '/fixtures/importSimple-exp.css', 'utf8'); | ||
request(app) | ||
.get('/import.css') | ||
.expect(200) | ||
.expect(expected) | ||
.expect(checkCacheFile(cacheFile, __dirname + '/fixtures/cacheFile-exp2.json')) | ||
.end(done); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3
29551
567
+ Addedajv@6.12.6(transitive)
+ Addedasap@1.0.0(transitive)
+ Addedasn1@0.2.6(transitive)
+ Addedassert-plus@1.0.0(transitive)
+ Addedasynckit@0.4.0(transitive)
+ Addedaws-sign2@0.7.0(transitive)
+ Addedaws4@1.13.2(transitive)
+ Addedbcrypt-pbkdf@1.0.2(transitive)
+ Addedcaseless@0.12.0(transitive)
+ Addedcombined-stream@1.0.8(transitive)
+ Addedcore-util-is@1.0.2(transitive)
+ Addeddashdash@1.14.1(transitive)
+ Addeddelayed-stream@1.0.0(transitive)
+ Addedecc-jsbn@0.1.2(transitive)
+ Addederrno@0.1.8(transitive)
+ Addedextend@3.0.2(transitive)
+ Addedextsprintf@1.3.0(transitive)
+ Addedfast-deep-equal@3.1.3(transitive)
+ Addedfast-json-stable-stringify@2.1.0(transitive)
+ Addedforever-agent@0.6.1(transitive)
+ Addedform-data@2.3.3(transitive)
+ Addedgetpass@0.1.7(transitive)
+ Addedhar-schema@2.0.0(transitive)
+ Addedhar-validator@5.1.5(transitive)
+ Addedhas@1.0.4(transitive)
+ Addedhttp-signature@1.2.0(transitive)
+ Addedimage-size@0.3.5(transitive)
+ Addedis@3.3.0(transitive)
+ Addedis-typedarray@1.0.0(transitive)
+ Addedisstream@0.1.2(transitive)
+ Addedjsbn@0.1.1(transitive)
+ Addedjson-schema@0.4.0(transitive)
+ Addedjson-schema-traverse@0.4.1(transitive)
+ Addedjsprim@1.4.2(transitive)
+ Addedless@2.4.0(transitive)
+ Addedmime@1.6.0(transitive)
+ Addedmime-db@1.52.0(transitive)
+ Addedmime-types@2.1.35(transitive)
+ Addednode.extend@1.1.8(transitive)
+ Addedoauth-sign@0.9.0(transitive)
+ Addedperformance-now@2.1.0(transitive)
+ Addedpromise@6.1.0(transitive)
+ Addedprr@1.0.1(transitive)
+ Addedpsl@1.10.0(transitive)
+ Addedpunycode@2.3.1(transitive)
+ Addedqs@6.5.3(transitive)
+ Addedrequest@2.88.2(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedsource-map@0.2.0(transitive)
+ Addedsshpk@1.18.0(transitive)
+ Addedtough-cookie@2.5.0(transitive)
+ Addedtunnel-agent@0.6.0(transitive)
+ Addedtweetnacl@0.14.5(transitive)
+ Addeduri-js@4.4.1(transitive)
+ Addeduuid@3.4.0(transitive)
+ Addedverror@1.10.0(transitive)
- Removedasn1@0.1.11(transitive)
- Removedassert-plus@0.1.5(transitive)
- Removedasync@0.9.2(transitive)
- Removedaws-sign2@0.5.0(transitive)
- Removedboom@0.4.2(transitive)
- Removedclean-css@2.2.23(transitive)
- Removedcombined-stream@0.0.7(transitive)
- Removedcommander@2.2.0(transitive)
- Removedcryptiles@0.2.2(transitive)
- Removedctype@0.5.3(transitive)
- Removeddelayed-stream@0.0.5(transitive)
- Removedforever-agent@0.5.2(transitive)
- Removedform-data@0.1.4(transitive)
- Removedhawk@1.1.1(transitive)
- Removedhoek@0.9.1(transitive)
- Removedhttp-signature@0.10.1(transitive)
- Removedis@0.3.0(transitive)
- Removedless@1.7.5(transitive)
- Removedmime@1.2.11(transitive)
- Removedmime-types@1.0.2(transitive)
- Removedmkdirp@0.3.5(transitive)
- Removednode-uuid@1.4.8(transitive)
- Removednode.extend@1.0.10(transitive)
- Removedoauth-sign@0.3.0(transitive)
- Removedqs@1.0.2(transitive)
- Removedrequest@2.40.0(transitive)
- Removedsntp@0.2.4(transitive)
- Removedsource-map@0.1.43(transitive)
- Removedstringstream@0.0.6(transitive)
- Removedtldts@6.1.59(transitive)
- Removedtldts-core@6.1.59(transitive)
- Removedtough-cookie@5.0.0(transitive)
- Removedtunnel-agent@0.4.3(transitive)
Updatedless@2.4.x
Updatedmkdirp@~0.5
Updatednode.extend@~1.1