New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

grunt-packer

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

grunt-packer - npm Package Compare versions

Comparing version 0.2.5 to 0.3.0

test/0.2

226

lib/pack-css-task.js

@@ -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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc