grunt-packer
Advanced tools
Comparing version 0.2.5 to 0.3.0
@@ -5,40 +5,4 @@ var path = require('path'), | ||
async = require('async'), | ||
postcss = require('postcss'), | ||
postcssUrl = require('postcss-url'), | ||
postcssImport = require('postcss-import'); | ||
postcss = require('postcss'); | ||
var rebaseUrlsPlugin = postcssUrl({ | ||
url: 'rebase' | ||
}); | ||
var removeVersionizedUrlsPlugin = postcss.plugin('unversionize', function() { | ||
function removeVersionizedUrls(s) { | ||
return s.replace(/\.v[a-z0-9]+/gi, ''); | ||
} | ||
return function(css, result) { | ||
css.eachInside(function(node){ | ||
if (node.type == 'atrule' && node.name == 'import') { | ||
node.params = removeVersionizedUrls(node.params); | ||
} | ||
}) | ||
} | ||
}); | ||
var inlineImportPlugin = postcssImport({ | ||
plugins: [ removeVersionizedUrlsPlugin ] | ||
}); | ||
function toCSSString(root) { | ||
return root.toResult().css; | ||
} | ||
function concatTo(concatRoot) { | ||
return function(singleRoot) { | ||
concatRoot.append(singleRoot); | ||
} | ||
} | ||
function resolveUrl(root, code, cssDir) { | ||
@@ -84,103 +48,60 @@ var matchResult = code.match(/url\((?!("|')?data:)[^#\)]+?\)/ig); | ||
/** | ||
* Пакует содерживое указанный файлов в один или несколько блоков (по max batchSize селекторов в каждом) | ||
* Если кол-во селекторов (numSelectors) превышает batchSize, создается numSelectors/batchSize файлов | ||
* В каждом из которых будет numSelectors/numFiles селекторов (для более равномерного распределения по пачкам) | ||
* Возвращает массив с элементами-пачками | ||
* | ||
* @param {Array} files | ||
* @param {String} root | ||
* @param {Number} batchSize=4000 | ||
* @param {Function} callback | ||
* @private | ||
*/ | ||
function _packWithInliningAndSplitting(files, root, batchSize, callback) { | ||
function splitIntoBatches(numSelectorsPerBatch, content) { | ||
async.map(files, function(cssFile, cb){ | ||
fs.readFile(cssFile, function(err, content){ | ||
if (err) { | ||
cb(err); | ||
} else { | ||
try { | ||
var result = postcss() | ||
.use(removeVersionizedUrlsPlugin) | ||
.use(inlineImportPlugin) | ||
.use(rebaseUrlsPlugin) | ||
.process(content.toString(), { | ||
safe: true, | ||
from: cssFile, | ||
to: path.join(root, 'fake.css') | ||
}); | ||
cb(null, result.root); | ||
} catch (e) { | ||
cb(e); | ||
} | ||
} | ||
}); | ||
}, function(err, results){ | ||
if (err) { | ||
callback(err); | ||
} else { | ||
var | ||
concatRoot = postcss.root(), | ||
chunks = [], | ||
numBatches, | ||
currentChunk = postcss.root(); | ||
var | ||
batches = [], | ||
numSelectorsInCurrentBatch = 0; | ||
results.forEach(concatTo(concatRoot)); | ||
function mkBatch() { | ||
var batch = postcss.root(); | ||
batches.push(batch); | ||
numSelectorsInCurrentBatch = 0; | ||
return batch; | ||
} | ||
numBatches = Math.ceil(concatRoot.nodes.length / (batchSize || 4000)); | ||
function serializeChildren(node) { | ||
return node.nodes ? node.nodes.reduce(fastSerialize, '{') + '}' : ''; | ||
} | ||
if (numBatches <= 1) { | ||
callback(null, toCSSString(concatRoot)); | ||
return; | ||
} | ||
function fastSerialize(memo, node) { | ||
if (node.type == 'decl') { | ||
return memo + node.prop + ':' + node.value + ';'; | ||
} | ||
else if (node.type == 'rule') { | ||
return memo + node.selector + serializeChildren(node); | ||
} | ||
else if (node.type == 'atrule') { | ||
return memo + '@' + node.name + ' ' + node.params + (node.nodes ? serializeChildren(node) : ';'); | ||
} | ||
return memo | ||
} | ||
batchSize = Math.ceil(concatRoot.nodes.length / numBatches); | ||
function toCSSString(root) { | ||
return root.nodes.reduce(fastSerialize, ''); | ||
} | ||
concatRoot.each(function(decl){ | ||
if (currentChunk.nodes.length < batchSize) { | ||
currentChunk.append(decl); | ||
} | ||
postcss.parse(content).nodes.reduce(function splitRulesToBatches(batch, node) { | ||
if (currentChunk.nodes.length == batchSize) { | ||
chunks.push(currentChunk); | ||
currentChunk = postcss.root(); | ||
// Считать селекторы будем только для CSS-правил (AtRules и т.п. - игнорируем) | ||
if (node.type == 'rule') { | ||
var numSelectorsInThisRule = node.selectors.length; | ||
// Если в пачке уже что-то есть и текущий селектор в нее не влезает - переносим в другую пачку | ||
// но в пустую пачку можно добавить блок, превышающий ограничения | ||
if (numSelectorsInCurrentBatch > 0) { | ||
if (numSelectorsInCurrentBatch + numSelectorsInThisRule > numSelectorsPerBatch) { | ||
batch = mkBatch(); | ||
} | ||
}); | ||
if (currentChunk.nodes.length > 0) { | ||
chunks.push(currentChunk); | ||
} | ||
callback(null, chunks.map(toCSSString)); | ||
numSelectorsInCurrentBatch += numSelectorsInThisRule; | ||
} | ||
}); | ||
} | ||
/** | ||
* Собирает несколько CSS-файлов в один переписывая урлы. Поднимает импорты ввех без инлайнинга. | ||
* Не создает файлы | ||
* | ||
* @param {Array} files | ||
* @param {String} root | ||
* @param {Function} callback | ||
* @private | ||
*/ | ||
function _fastPackNoInline(files, root, callback) { | ||
async.map(files, function(css, cb){ | ||
fs.readFile(css, function(err, content){ | ||
if (err) { | ||
cb(err); | ||
} else { | ||
cb(null, resolveUrl(root, content.toString(), path.dirname(css))); | ||
} | ||
}); | ||
}, function(err, results){ | ||
if (err) { | ||
callback(err); | ||
} else { | ||
callback(null, bumpImportsUp(results.join('\n'))); | ||
} | ||
}); | ||
batch.append(node); | ||
return batch; | ||
}, mkBatch()); | ||
batches = batches.map(toCSSString); | ||
return batches; | ||
} | ||
@@ -243,35 +164,24 @@ | ||
/** | ||
* Собирает несколько css-файлов в один, переписывая URLы на правильные (с учетом нового местоположения итогового файла). | ||
* Возвращает результат паковки. Не создает файлов! | ||
* | ||
* Опции: | ||
* inlineImports: false - выполнять ли обработку найденных директив @import | ||
* batchSize: 4000 - имеет смысл только при inlineImports = true. Разбивает итоговый файл на пачки по batchSize селекторов | ||
* | ||
* @param {Array} files пути до файлов, которые нужно собрать | ||
* @param {String} root папка, в которуй будет размещен итоговый файл | ||
* @param {Object} [options={inlineImports: false}] Опции | ||
* @param {Function} callback | ||
* @returns {*} | ||
*/ | ||
nativePackCSS: function(files, root, options, callback) { | ||
if (typeof options == 'function') { | ||
callback = options; | ||
options = { | ||
inlineImports: false | ||
}; | ||
} | ||
nativePackCSS: function (files, root, callback) { | ||
async.map(files, function(css, cb){ | ||
fs.readFile(css, function(err, content){ | ||
if (err) { | ||
cb(err); | ||
} else { | ||
cb(null, resolveUrl(root, content.toString(), path.dirname(css))); | ||
} | ||
}); | ||
}, function(err, results){ | ||
if (err) { | ||
callback(err); | ||
} else { | ||
callback(null, splitIntoBatches(4000, bumpImportsUp(results.join('\n')))); | ||
} | ||
}); | ||
}, | ||
options = options || {}; | ||
if (options.inlineImports) { | ||
return _packWithInliningAndSplitting(files, root, options.batchSize, callback); | ||
} else { | ||
return _fastPackNoInline(files, root, callback); | ||
} | ||
}, | ||
resolveUrl: resolveUrl, | ||
bumpImportsUp: bumpImportsUp | ||
bumpImportsUp: bumpImportsUp, | ||
__splitIntoBatches: splitIntoBatches | ||
}; | ||
}; |
{ | ||
"name": "grunt-packer", | ||
"description": "Grunt plugin to automagically concat JS and CSS files found in HTML", | ||
"version": "0.2.5", | ||
"version": "0.3.0", | ||
"author": "Oleg Elifantiev <oleg@elifantiev.ru>", | ||
@@ -17,4 +17,2 @@ "contributors": [], | ||
"postcss": "^4.1.16", | ||
"postcss-import": "^6.2.0", | ||
"postcss-url": "^4.0.0", | ||
"tensor-xmldom": "0.1.18" | ||
@@ -21,0 +19,0 @@ }, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
1035287
4
18579
0
20
1
- Removedpostcss-import@^6.2.0
- Removedpostcss-url@^4.0.0
- Removedbalanced-match@1.0.2(transitive)
- Removedbrace-expansion@1.1.11(transitive)
- Removedclone@0.1.19(transitive)
- Removedconcat-map@0.0.1(transitive)
- Removeddirectory-encoder@0.6.1(transitive)
- Removedfs-extra@0.8.1(transitive)
- Removedfunction-bind@1.1.2(transitive)
- Removedglob@5.0.15(transitive)
- Removedhandlebars@1.1.2(transitive)
- Removedhasown@2.0.2(transitive)
- Removedimg-stats@0.4.2(transitive)
- Removedinflight@1.0.6(transitive)
- Removedis-core-module@2.16.1(transitive)
- Removedjsonfile@1.1.1(transitive)
- Removedlodash@2.4.0(transitive)
- Removedmime@1.6.0(transitive)
- Removedminimatch@3.1.2(transitive)
- Removedminimist@1.2.8(transitive)
- Removedmkdirp@0.3.50.5.6(transitive)
- Removedncp@0.4.2(transitive)
- Removedobject-assign@3.0.0(transitive)
- Removedonce@1.4.0(transitive)
- Removedoptimist@0.3.7(transitive)
- Removedpath-is-absolute@1.0.1(transitive)
- Removedpath-parse@1.0.7(transitive)
- Removedpostcss-import@6.2.0(transitive)
- Removedpostcss-message-helpers@2.0.0(transitive)
- Removedpostcss-url@4.0.1(transitive)
- Removedreduce-function-call@1.0.3(transitive)
- Removedresolve@1.22.10(transitive)
- Removedsource-map@0.1.43(transitive)
- Removedsupports-preserve-symlinks-flag@1.0.0(transitive)
- Removeduglify-js@2.3.6(transitive)
- Removedwordwrap@0.0.3(transitive)
- Removedwrappy@1.0.2(transitive)
- Removedxmldom@0.1.16(transitive)