Синхронная меньшая компиляция в NodeJS

Я пытаюсь написать сценарий преобразования для Browserify, который позволяет мне require() .less файлов. Трансформация скомпилирует их в CSS, а затем обернет этот минимизированный CSS в небольшую функцию Javascript, которая добавит CSS на страницу.

Моя проблема в том, что основной модуль LESS является асинхронным, и, похоже, он не работает вместе с преобразованием. сценарий:

lessify/index.js (смоделировано непосредственно из узла -подчеркнуть)

var less = require('less');
var cleanCSS = require('clean-css');
var through = require('through');

module.exports = function(file) {
    if (!/\.css|\.less/.test(file)) {
        return through();
    }
    var buffer = "";

    return through(function(chunk) {
        return buffer += chunk.toString();
    }, function() {
        compiled = buffer;
        if (/\.less/.test(file)) {
            compiled = less.render(compiled, function(e, r) { return r; });
        }
        // rv comments
        compiled = compiled.replace(/\/\*.*?\*\//g, "");

        // minify. TO DO: Get less.js to do this for us
        var compiled = cleanCSS.process(buffer);

        compiled = "(function($) { $('head').append('<style type=\"text/css\">" + compiled.replace(/'/g, "\\'") + "</style>');}(window.jQuery));";
        this.queue(compiled);
        return this.queue(null);
    });
};

Это прекрасно работает для файла .css, но не работает с файлами .less, поскольку compiled не определено.

Есть несколько завершенных запросы на вытягивание в источнике less.js, связанные с этим, но, похоже, ни один из них не работает для меня.

Я не очень хорошо знаком с библиотекой through, поэтому, возможно, ее поведение можно легко настроить для асинхронных функций? Я понимаю, что less.render() имеет смысл быть асинхронным по умолчанию для обработки @import, и не возражаю против отказа от импорта, чтобы иметь возможность напрямую require() МЕНЬШЕ на моих страницах.


person Chris Wilson    schedule 13.11.2013    source источник


Ответы (1)


Это действительно работает, если немного изменить. Выше я был глуп, запуская cleanCSS на buffer, а не на compiled

var less = require('less');
var cleanCSS = require('clean-css');
var through = require('through');

var parser = new(less.Parser)({
    processImports: false
});

module.exports = function(file) {
    if (!/\.css|\.less/.test(file)) {
        return through();
    }
    var buffer = "";

    return through(function(chunk) {
        return buffer += chunk.toString();
    }, function() {
        var compiled;
        // CSS is LESS so no need to check extension
        parser.parse(buffer, function(e, r) { 
            compiled = r.toCSS();
        });

        // rv comments
        compiled = compiled.replace(/\/\*.*?\*\//g, "");

        var compiled = cleanCSS.process(compiled);

        compiled = "(function($) { $('head').append('<style type=\"text/css\">" + compiled.replace(/'/g, "\\'") + "</style>');}(window.jQuery));";
        this.queue(compiled);
        return this.queue(null);
    });
};
person Chris Wilson    schedule 13.11.2013