bem-site / bem-forum-content-ru

Content BEM forum for Russian speak users
MIT License
56 stars 6 forks source link

TechBuilder: Придумать API #6

Open tadatuta opened 10 years ago

tadatuta commented 10 years ago

Здесь собираем варианты API TechBuilder, выбираем наиболее подходящий.

tadatuta commented 10 years ago

@SevInf: По аналогии с LevelBuilder: Инстанс конструктора создается вызовоам BEM.defineTech(). Непосредственно для создания класса используется метод createClass() конструктора. Базовый билдер: setCreateSuffixes() addCreateSuffixes() setBuildSuffixes() addBuildSuffixes() setDependencies() addDependencies() buildChunk(callback) build(callback) create(callback) setDefaultMakeMethod() Расширение билдера делается методами самого билдера. Метод addParam() автоматически генерирует методы для установки параметоров технологии (set<Param>() и/или add<Param>()). Пара примеров: Технология import-files, собирающая выходной файл путем импортов из исходных:

module.exports = function(BEM) {
    return BEM.defineTech()
        .buildChunk(function(file) {
            //этот метод станет getBuildResultChunk в классе технологии
            return this.params.importTpl(file);
        })
        .addParam('importTpl', {

            //сгенерирует метод setImportTpl у билдера import-files
            set: function(value) {

                //возвращаемое значение метода попадет в this.params. В данном случае
                //это underscore- шаблон
                return _.template(value);
            }
        })
        .createClass();
};

На базе не можно делать технологию css:

module.exports = function(BEM) {
    return BEM.defineTech('import-files') //задаем имя базовой технологии
        .setBuildSuffixes('css')
        .setImportTpl('@import url("<%=relPath %>")')
        .createClass();
};

Или js-i:

module.exports = function(BEM) {
    return BEM.defineTech('import-files')
        .setBuildSuffixes('js')
        .setImportTpl('/*borschik:include:<%=relPath %>')
        .createClass();
};

Из которой в свою очередь можно сделать browser.js:

module.exports = function() {
    return BEM.defineTech('js')
        .addBuildSuffixes('js', ['vanilla.js', 'browser.js'])
        .createClass();
};
tadatuta commented 10 years ago

@scf2k: Я бы оторвал set/add у названий методов чтобы короче было. @diunko: Если оторвать set/add, как их различать?

tadatuta commented 10 years ago

@tadatuta: я правильно понимаю, что Было:

exports.techMixin = {

    getBuildResultChunk: function(relPath) {
        return '/*borschik:include:' + relPath + '*/;\n';
    },

    getBuildSuffixesMap: function() {
        return {
            'js': ['js']
        };
    }

}

Стало:

module.exports = function(BEM) {
    return BEM.defineTech('import-files')
        .setBuildSuffixes('js')
        .setImportTpl('/*borschik:include:<%=relPath %>')
        .createClass();
};

и, грубо говоря, весь профит от TechBuilder в возможности не писать function и return?

tadatuta commented 10 years ago

@scf2k: И в одном файле. @arikon: @tadatuta В конкретном случае — да. Но ещё упрощается процесс расширения существующих технологий (создаёшь объект-билдер из готовой технологии и зовёшь его хелперы), и технологии начинают предоставлять свои конкретные хелперы для конфигурирования себя.

tadatuta commented 10 years ago

@arikon build(callback) create(callback) Куда применится переданный в эти методы callback? Будет использован в качестве getCreateResult() и getBuildResult()?

tadatuta commented 10 years ago

@arikon: Не очень понял про addParam(name, {}). Что можно передавать в качестве {}, какие там могут быть ключи, помимо set?

возвращаемое значение метода попадет в this.params

this.params в контексте какого объекта?

tadatuta commented 10 years ago

@SevInf:

как расширить существующую технологию и добавить ей хелперов для билдера?

Если существующая технология написана с использованием билдера - то как-то так:

BEM.defineTech('existing-tech')
   .addParam('extSuffix', {
       set: function(value) {
           this.addBuildSuffixes('ext.' + value, [value]);
       }
   });

Если речь про технологии, написание как через techMixin - я не думаю, что это нужно. Если все-таки нужно - надо продумать, сейчас ответить не могу.

Куда применится переданный в эти методы callback? Будет использован в качестве getCreateResult() и getBuildResult()?

Да. С чего-то надо начинать строить самые базовые технологии.

Что можно передавать в качестве {}, какие там могут быть ключи, помимо set

По аналогии с LevelBuilder думал сделать set и/или add

this.params в контексте какого объекта?

Немного некорректно выразился. params в итоговом классе технологии предлагаю сдеалать свойством прототипа или статическим свойством класса. Тогда инстанс сможет получить параметры через instance.params или instance.__self.params

По аналогии с LevelBuilder думал сделать set и/или add

Сигнатура для add:

add: function(prev, arg1, arg2...) {
}

Типичные варианты использования:

add: function(prev, value) {
    prev = prev || [];
    return prev.concat(value);
}
add: function(prev, key, value) {
    prev = prev || {};
    prev[key] = value;
    return prev;
}
tadatuta commented 10 years ago

@arikon: Если у меня есть готовая технология, лежащая в пакете. Как мне расширить её?

Если речь про технологии, написание как через techMixin - я не думаю, что это нужно. Если все-таки нужно - надо продумать, сейчас ответить не могу.

Не думаю, что это нужно. Перепишем все технологии на использование билдера.

tadatuta commented 10 years ago

@SevInf:

Если у меня есть готовая технология, лежащая в пакете. Как мне расширить её?

Думаю, логично будет сделать по аналогии с LevelBuilder:

var NewTech = OldTech.extend()
    .someBuilderMethod()
    .someOtherBuilderMethod()
    .createClass();

extend создает и возвращает точную копию билдера, используемого при создании OldTech. Последующими вызовами его можно доконфигугрировать, не затрагивая OldTech

tadatuta commented 10 years ago

@SevInf: Чем больше погружаюсь в эту задачу, тем больше кажется что все проблемы которые мы хотим решить билдером можно в принципе решить более внятной иерархией классов технологий с правильными абстрактными классами и виртуальными методами в нужных местах. B в этом случае @tadatuta прав, профит от билдера будет не очень большим. По настоящему сделать API более гибким помог бы пересмотр flow базовой технологии, например в такую сторону:

  1. create как часть сборки уходит, остается один build;
  2. build принимает на вход декларацию, список уровней и опциональный префикс;
  3. Базовая технология получает метод buildFile(prefix, suffix, callback) внутри каллбека происходит подбор исходных файлов и сборка выходного. Возвращает промис на строку/буфер которая попадет в выходной файл;
  4. Базовая технология получает методы для получения исходных файлов: getFile(prefix, suffix), getFilesFromLevels(levels, suffix) и тому подобные. Эти методы могут вызваться толко внутри каллбека buildFiles и в момент вызова происходит следующее:
    1. Сами методы возвращают один или несколько путей к исходным файлам;
      1. Факт вызова такого метода, его параметры, списки найденых файлов и их mtime сохраняются в кеше для текущего собираемого выходного файла;
      2. При повторном вызове buildFile с тем же префиксом и суффиксом все эти операции поднимаются из кеша, уровни повторно сканируются, новые списки файлов сравниваются с предыдущими и если они не изменились со времени прошлой сборки то вызов каллбека buildFiles не происходит.

Профит:

  1. create не вызывается в процессе сборки и не выносит людям мозг
  2. любой исходный файл задействованный в процессе сборки какого-либо выходного автоматически попадет в кеш (привет, интернационализация!)
  3. технология больше не ограничена двумя вариантами выполнения, она может использовать и как старые flow, их произвольную комбинацию, так и собираться совсем как ей хочется;
  4. уйдут также get<Something>SuffixesMap
  5. старые базовые технологии можно будет реализовать поверх этого API не ломая совместимость

Пара примеров (просьба воспринимать это скорей как псевдокод, чем реальное предложение API). Вот как в этом случае может выглядеть гипотетический js-i:

{
    build: function(decl, levels, outputPrefix) {
        this.buildFile(outputPrefix, 'js', function() {
            return this.getFilesFromLevels(levels, ['js'])
                .then(function(files) {
                    return files.map(function(file) {
                        return '/*borschik:include ' + file.relPath + '*/';
                    }).join('\n');
                })
        });
    }
}

А вот так html (попутно он сможет научиться собираться на нескольких уровнях, например desktop.blocks и touch.blocks и для нескольких бандлов сразу):

{
    build: function(decl, levels) {

        levels.forEach(function(level) {
            decl.deps.forEach(function(item) {
                this.buildFile(level.getPrefixFor(item), 'html', function() {
                    var bemhtml = this.getFile(level.getPrefixFor(item), 'bemhtml.js');    
                    var bemjson = this.getFile(level.getPrefixFor(item), 'bemjson.js');
                    return bemhtml.apply(bemjson);
                })
            }, this);
        }, this);
    },
}

Для подобной базовой технологии билдер может все также иметь описанное выше API. Либо, новая базовая технология может изначально иметь builder-style API. @arikon, @tadatuta, @nar, нужен фидбек. Есть ли смысл в предложении в принципе, есть ли смысл в предложении в рамках bem-tools 1.0.0?

tadatuta commented 10 years ago

@arikon: Сразу непонятно со сборкой html и другими технологиями, которые сейчас выполняются как create(). Что в этом случае decl и levels? Как будут выражаться и удовлетворяться зависимости для сборки html сразу в нескольких бандлах и уровнях?

tadatuta commented 10 years ago

@narqo: Кажется, я уже сильно выпал из контекста всего, что около внутренностей bem-tools. Я правильно понимаю, что технологии перестают быть завязаны на декларации в уровнях и становятся нормальными сборщиками? (по крайней мере везде используются суффиксы конечных файлов, а не названия технологий) — про что-то такое мы говорили в одном из PR на gh. Еще не очень понимаю пример с html. Сейчас сборка html-файла, это: 1) прочитай bemjson, 2) прочитай bemhtml, 3) выполни bemhtml.apply(bemjson). У тебя в примере получается, что файлы для this.getFile будут искаться в уровнях пришедших из парамета levels. Это немного странно (опять же, в текущем Мире, может что-то поменялось):

для сборки bemhtml нужно будет передавать набор уровней с блоками (common.blocks, desktop.blocks, и т.д.), для сборки html — набор уровней (на самом деле один уровень?) с бандлами (desktop.bundles).

За счет чего уйдет get*SuffixesMap? Те же самые данные, ты сейчас хардкодишь в this.buildFile(outputPrefix, 'js', fn) и this.getFilesFromLevels(levels, ['js']). В остальном, мне эта идея нравится больше чем TechBuilder, который я, пока, не понимаю :(

tadatuta commented 10 years ago

@SevInf:

Про html: Побочный эффект от такого способа объединения - одна create-команда может собирать файлы на нескольких уровнях. Гипотетический вызов html может выглядеть так:

  1. levels=desktop.bundles, touch-phone.bundles;
  2. decl - список страниц которые надо собрать. Например [{block: "index"}, {block: "page1"}, ...] В итоге соберется desktop.bundles/index/index.html, desktop.bundles/page1/page1.html, touch-phone.bundles/index/index.html, touch-phone.bundles/page1/page1.html. Если такая возможность считается бесполезной, то есть альтернативный вариант:
  3. build принимает на вход только путь к текущему собираемому бандлу.
  4. Если эта технология сейчас работает через create - она продолжает работать также как и раньше - читает нужные исходники и пишет нужные выходные файлы.
  5. То что сейчас работает через build читает декларацию из бандла явно.
  6. Для build-технологий нужна возможность получить список исходных уровней для бандла. Ныне покойный bundleBuildLevels отлично бы для этого подошел.

Я правильно понимаю, что технологии перестают быть завязаны на декларации в уровнях и становятся нормальными сборщиками?

По сути да. В предлагаемом варианте технология - это просто что-то что переводит набор входных файлов в набор выходных. При этом, как и откуда брать исходники решает сам автор модуля, никакого фиксированного flow в базовой технологии не предполагается.

За счет чего уйдет get*SuffixesMap? Те же самые данные, ты сейчас хардкодишь в this.buildFile(outputPrefix, 'js', fn) и this.getFilesFromLevels(levels, ['js']).

Я больше всякие штуки вроде weakSuffixes имел ввиду. Ту же задачу можно было бы решить не созданием новой, довольно странной и неочевидной сущности в базовой технологии, а созданием альтернативного flow для суммарных технологий. Данные от buildSuffixes в том или ином виде все равно останутся, но пропадает необходимость их явно декларировать для того чтобы они попали в кеш - если для сборки нам надо прочитать что-то по нестандартному пути мы просто делаем это без всяких костылей.

Если такая возможность считается бесполезной, то есть альтернативный вариант:

На самом деле, этот альтернативный вариант теперь мне нравиться больше чем изначальное предложение. Примеры псевдокода для тех же js-i и html:

{
    build: function(bundleLevel) {
        this.buildFile(bundleLevel.prefix, 'js', function() {

            return this.readFile(bundleLevel.prefix, 'bemdecl.js')
                .then(function(decl) {
                    return this.getFilesByDecl(decl, bundleLevel.getSourceLevels(), ['js']);
                })
                .then(function(files) {
                    return files.map(function(file) {
                        return '/*borschik:include ' + file.relPath + '*/';
                    }).join('\n');
                });
        });
    }
}
{
    build: function(bundleLevel) {
        this.buildFile(bundleLevel.prefix, 'html', function() {
            return this.readFile(bundleLevel.prefix, 'bemhtml.js')
                .then(function(bemhtml) {
                    return [bemhtml, this.readFile(bundleLevel.prefix, 'bemjson.js')];
                })
                .spread(function(bemhtml, bemjson) {
                    return bemhtml.apply(bemjson);
                });    
        })
    },
}

Надо только договориться насчет bundleLevel.getSourceLevels().

tadatuta commented 10 years ago

В тред призываются @bem/owners и @zxqfox

qfox commented 10 years ago

Я, в целом, со согласен с @SevInf, и, как мне казалось, говорил про тоже самое. Ведь сами технологии — это плоский список трансформаций чего-то, описанный для уровня, а чаще и для всего проекта в целом, он будет знать что и из чего он собирает, и просто делать это.

Кроме этого, я еще хотел, но озвучивал по своему, вынести всяческие getFile куда-нибудь в bem-levels, или вообще отдельно, в bem-fs, может. Т.к. уровни у нас отвечают в т.ч. за именования в них — возможно, в нем эти getFile будут вполне ожидаемы. В любом случае, getFile, разбросанные по базовым уровням, технологиям, и т.д. — это зло. Реализации технологий (bemjson, bemhtml, deps) — это кирпичики, они всегда лежат в одинаковых местах и их можно провайдить одинаково в указанные технологии. Можно читать директории блоков и заранее узнавать про них, можно их даже читать. Опять же, если у нас будет 1 провайдер — у нас появится возможность из памяти провайдить как прочитанные с диска, так и собранные файлы реализаций технологий. Скажем, если мы говорим, что собираем html из bemjson, а bemjson у нас нет, но есть bemyaml, который может быть 1к1 трансформирован в bemjson технологией, которая заявила, что может это сделать — то мы делаем это, и сразу отдаем результат в технологию bemjson, а параллельно можем записать и bemjson, а можем и не писать — это становится не важно.

Есть еще мнение, что работать c getFile можно не напрямую из технологий, а из низкоуровневых модулей, типа bem-techs, может быть из базового класса технологии, да. А на высоком уровне, где мы будем описывать само преобразование lambda, у нас будет интерфейс аля Array или даже jQuery, которые позволят собирать все фильтры, мапы, редьюсы, лениво подгружать все нужное и отдавать в build самих технологий при необходимости. Т.е. если завернуть всю логику трансформаций в некую абстрактную коллекцию — сами лямбды станут легковесными и понятными, как раз для домохозяек. Скорость работы при этом не должна упасть, разве что на 5-10%, за счет создания небольшого кол-ва функций и их call'ов.

И последнее мнение — построение графа (deps) тоже можно описать технологией, обернуть в коллекцию, возможно даже с аналогичным интерфейсом, но несколько другой логикой внутри. Все таки с графом работаем.

В общем случае есть два вида преобразований: λt→t, λt→λ. Вторая, мне кажется, сводится к первой. Если вдаваться в подробности, то в одну λ может попадать разное кол-во входных данных, условно — λt[], λtw, λλt, которые тоже должны сводится к первой. Не суть.

Условно, технологии описывают преобразования: bemtree.js(bemtree[все кусочки со всех блоков]) → bemtree, если надо bemhtml.js(bemhtml[все кусочки со всех блоков]) → bemhtml, если надо [bemyaml(data.yaml) или bemtree(data.json) → bemjson], bemhtml(bemjson) → html Собрав все, а это можно сделать при старте прочитав make и levels, это подграф из всех известных исходников и целей. Узлы — реализации или данные (условно, term), хорды — преобразования (условно, lambda). Поскольку могут быть случаи, когда возможно собрать из разных источников — жедательно где-то указывать порядок, либо же брать из порядка декларации/подключения технологий.

build: function (bundleLevel) {
    // тут стоит оставить html, bundleLevel.prefix — лучше убрать за интерфейс bem-fs или bem-levels
    this.buildFile(bundleLevel.prefix, 'html', function() {
            // prefix туда же, по той же причине
            // про bemhtml.js должна знать зависимая от html лямбда
            return this.readFile(bundleLevel.prefix, 'bemhtml.js')
                .then(function(bemhtml) {
                    // через которую мы узнаем и про bemjson.js
                    return [bemhtml, this.readFile(bundleLevel.prefix, 'bemjson.js')];
                })
                .spread(function(bemhtml, bemjson) {
                    // и тогда только это у нас останется в then колбеке в каком-то виде
                    // и только потому, что нам надо λ(λt)→t
                    // подозреваю, что и это можно будет описать
                    return bemhtml.apply(bemjson);
                });
        })
}
qfox commented 10 years ago
BEM.defineTech('existing-tech')
   .addParam('extSuffix', {

может быть лучше так?

BEM.defineTech('existing-tech', function (existingTech) {
  existingTech.defineProperty('extSuffix', {
    set: ...
  });
});

Или вообще через provide, как в ym.

SevInf commented 10 years ago

@zxqfox, правильно ли я понял, что технология js в твоем предложении будет выглядет как то так:

//allJs - все JS-файлы, собранные из блоков, array-like интерфейс.

var builtJS = allJs.map(function(file) {
    return '/*borscik:include ' + file.path + '*/';
}).reduce(function(file1, file2) {
   return file1 + file2;
});

При этом, сам allJS - продукт работы другой технологии. Сам builtJS в последствии может быть использован как исходник для какой-то другой технологии, например js+bemhtml?

qfox commented 10 years ago

@SevInf ± да. условно:

var allJs = all.reduce(function (node, result) {
  node.techs['vanilla.js'] && result.push(node.techs['vanilla.js'].name());
  return result;
}, []);
qfox commented 10 years ago

@SevInf Конечно же, частоиспользуемые вещи надо будет засахарить. reduce слегка сносит мозг. Да и закешировать тоже или предоставить интерфейс через какой-то модуль, например, тот же bem-core, который предоставляет сами технологии. Можно представить all как DB про БЭМ-объекты. Например, блоки — записи, технологии — поля, но могут быть представлены как записи, библиотеки — таблицы. Грубо, конечно, но близко к истине. В таком случае многое вообще становится не нужно, достаточно будет предоставить простой интерфейс (взять, положить, и т.д.) и описать язык взаимодействия.

SevInf commented 10 years ago

@zxqfox, да, кажется что это движение в правильном направлении. Сами сборщики на низком уровне тогда очень просто можно было бы описывать декларативно, a-la Rake/Jake/модульная система:

BEM.builder('allJs',  ['all'], function(all) {
    return all.reduce(...);
}); 

BEM.builder('js', ['allJs'], function(allJs) {
   return allJs.map(...)
});

BEM.builder('js+bemhtml',  ['js', 'bemhtml.js'], function(js, bemhtml) {
   return js.concat(bemhtml);
});
qfox commented 10 years ago

@SevInf :+1: Да, это именно то, о чем я думаю

SevInf commented 10 years ago

Кстати, заодно и хороший повод термин "технология" заменить на что-нибудь более очевидное, например "task" или "build step":)

qfox commented 10 years ago

Название надо придумать, да. Task ок в совокупности с builder.

Может быть возможность асинхронно провайдить тоже нужна? Какой тогда интерфейс лучше? UPD: promises.

BEM.builder('js+bemhtml',  ['js', 'bemhtml.js'], function(js, bemhtml) {
  var promise = some.promise();
  setTimeout(function () {
    promise.fulfill(js.concat(bemhtml));
  }, 500);
  return promise;
});
SevInf commented 10 years ago

Кажется, для асинхронности самым правильным, удобным и легкочитаемым будет возврат промиса.

qfox commented 10 years ago

@SevInf Да, согласен. Все время про них забываю. :aerial_tramway:

qfox commented 10 years ago

@SevInf А почему bem.builder ?

SevInf commented 10 years ago

@zxqfox, никакой конретной причины нет, просто чтобы псевдокод продемонстрировать. Если остановились на том, что это таск то наверное правильнее будет bem.task()

qfox commented 10 years ago

@SevInf завтра же сменю ник на @zqfox ;-) Только ведь в таком виде task не сходится с командами, которые выбрасываются в BEM.api и в coa. И еще, ноды полезны для deps, mergedBundles, еще для чего-то? Или merged как-то проще можно будет собрать?

qfox commented 10 years ago

Хотя, да, конечно можно будет проще:

all.filter({ merged }).reduce( ... )
SevInf commented 10 years ago

завтра же сменю ник на @zqfox ;-)

да ладно, я учусь потихоньку)

С командами, возможно, действительно не очень сходится. Есть пока слабо оформившаяся идея, сделать возможность объявлять некоторые таски вызываемыми как комманды:

BEM.task('make', ['js', 'css', 'html'], function(deps, cliOpts) {
//что-то делаем с опциями. что?
})
.command()
    .option('someOpt').short('o').long('opt')
    .arg('someArg')

Таким образом make можно будет вызвать из командной строки, передать ей опции и аргументы. Для того чтобы позвать make нам надо собрать, js, css и html. Для js в свою очередь нужен allJs. Для alJsl нужен all и так далее. Но идея очень сырая, и я не уверен что это мысль в правильном направлении. Пока такая штука больше вопросов вызывает, чем дает ответов:

  1. Как прокинуть опции нашим зависимостям?
  2. Что делать, если состав зависимости различный при различных опциях.
  3. Как собрать в такой схеме отдельный файл, а не весь бандл?

В общем, хотелось бы подтверждения или опровержения негодности этой идеи.

qfox commented 10 years ago

@SevInf что сейчас, что раньше — с трудом представляю как можно такие штуки из терминала использовать. Но, с другой стороны exec [-l bundle || cwd()] <task> может в stdout выплевывать результат работы, если это 1 файл. Иначе непонятно, как форматировать. Либо же еще -o file или -o path, чтобы оно туда все сохранило.

qfox commented 10 years ago

@SevInf т.е. не напрямую в коа, а через прослойку, которая специально для этих трансформаций сделана. Кстати, по смыслу это преобразование множеств, искал какое-то слово правильное, но кроме лямбды ничего в голову не пришло. Можно transformRule, или rule, а task оставить для команд, почему-то там мне оно ощущается более гармонично, чем в переходах, ближе к командной строке. Вообще, теория множеств и графы — это то, чем можно описать БЭМ, почти полностью. Если есть сложности с именованием — лучше обращаться к первоисточникам ;-), и классикам.

arikon commented 10 years ago

@SevInf @zxqfox Из треда не понял, что будет делать технологии all и allJS. Расскажите?

Лёша, ты уже начал где-то делать прототип?

arikon commented 10 years ago

@SevInf @zxqfox Если я правильно распарсил интерфейс билдера, то первым аргументом указывается имя описываемого билдера (технологии, таска), а вторым — его зависимости (другие билдеры / технологии / таски).

Статические зависимости сейчас в bem make, и я склоняюсь к мысли, что это скорее не очень удобно, чем наоборот. Какие ваши мысли на этот счёт?

qfox commented 10 years ago

@arikon Первый — то, что описываем, второй — что подтягиваем. Как в AMD. all и allJs — это все доступные для сборки технологии (реализации) и только Js-based соотв. Есть одна большая коллекция, мы её фильтруем/преобразовываем, получаем новые коллекции, технологии и, в итоге, результат. Но делаем мы это с конца, чтобы не собирать лишнее. Читаем декларации, вычисляем по дереву зависимостей что требуется, и оно само собирается при необходимости. Про статические зависимости — честно говоря, не понял о чем речь. Думаю, что в идеале такого быть не должно в принципе, потому что не нужно. Но там где нужно — возможность их использовать, думаю, есть. Ответил настолько же точно, насколько понял вопрос ;-)

qfox commented 10 years ago

Лёша, ты уже начал где-то делать прототип?

@arikon Да, конечно, но бОльшая часть пока в голове, будет стыдно, если станет видно. Уже надо? Есть же 1.0, если форсировать разработку 2.0, мы 1.0 перепрыгнем, оно же в альфе до сих пор.

arikon commented 10 years ago

@zxqfox Чем раньше от слов к делу, тем лучше ;) 1.0 ждёт своего героя — есть ещё пачка неокученных задач, которые обещал сделать @diunko.

qfox commented 10 years ago

@arikon Понял. У меня эта неделя слегка загруженная, но к концу недели я постараюсь формализовать и реализовать все то, что уже сформировалось. База почти вся ясна. Есть некоторые хотелки типа поддержки старых технологий, и с ними пока туман.

arikon commented 10 years ago

@zxqfox Я бы в 2.0 вообще не тащил никакого legacy

qfox commented 10 years ago

@arikon Даже через отдельный модуль-адаптер? ;-)

arikon commented 10 years ago

@zxqfox Как миниму, я бы не держал это в фокусе сейчас. Поиск решения — как это сделать — однозначно сужает спектр возможных технических решений для bem-tools@2.0.

qfox commented 10 years ago

@arikon Сергей, я тебя прекрасно понял ;-) И согласен.

SevInf commented 10 years ago

Вот этот сборщик в чем-то похож на звучащую здесь идею: сборка = серия простых преобразований над данными. Мне кажется, есть смысл н него посмотреть повнимательней.