bem / bem-components

Set of components for sites development
https://bem.info/libraries/classic/bem-components/6.0.0/
Other
333 stars 87 forks source link

BH: Do we really need module.exports wrapper #1286

Open tadatuta opened 9 years ago

tadatuta commented 9 years ago

@mishanga Do we really need module.exports wrapper for each BH template? We don't have it for BEMHTML templates. Is there real profit or we can just wrap concatenated templates as one of build steps?

qfox commented 9 years ago

For now you can use BH-files as node.js (read CommonJS) modules. If you strip these line you couldn't use them as modules.

So for now you can use a bunch of require('bh-file')(bhInstance) lines. So you don't need to read each file, concatenate, etc. And it's much faster for dev-env.

tadatuta commented 9 years ago

require() caches the source so you need to drop and "rerequire" again (which is actually happing now) so that's not so good as it seems

qfox commented 9 years ago

So you want to say if we can switch require with readFileSync() or something then we should load them all each time and it is almost the same? Agreed.

mishanga commented 9 years ago

Упс, не увидел этот тредик. Да, я за удаление из шаблонов этих оберток. Тогда не придется вырезать при сборке эти обертки: https://github.com/enb-bem/enb-bh/blob/master/lib/bh-client-processor.js#L11

shuhrat commented 9 years ago

+1

narqo commented 9 years ago

:+1:

tadatuta commented 9 years ago

it looks like major change so we can't release it until v3.0.0?

mishanga commented 9 years ago

yep

golyshevd commented 9 years ago

Умоляю не удаляйте обертку, зачем?

qfox commented 9 years ago

@golyshevd Это же опционально, и только в библиотеке.

golyshevd commented 9 years ago

Сейчас благодаря обертке шаблоны - модульные, видно где и как произошла ошибка, а сборка - сказка, просто список require-ов. Обрабатываешь c помощью browserify - и вот тебе клиентский код, по прежнему читаемый. А теперь надо будет делать какую-то странную сборку, часть файлов из либы оборачивать, а свои - нет.

Файл шаблона без обертки - это какой-то невалидный кусок кода, который даже линтер не поймет если ему явно не сказать про глобальные переменные. Нельзя писать use srtict. Гора исключений и хранимой в голове информации. Любой импорт вверху файла будет импортом на все шаблоны => edge case баги.

Я только что выбрал любимый шаблонизатор, но это нововведение совсем не понимаю, зачем изобретать свою модульность если на сервере она есть нативная

Это для чего вообще все?

UPD сс @remnev

golyshevd commented 9 years ago

Тогда не придется вырезать при сборке эти обертки: https://github.com/enb-bem/enb-bh/blob/master/lib/bh-client-processor.js#L11

@mishanga а технология для сборки клиентского BH - вообще "произведение искусства", мы как только увидели как она работает (обрезает), так сразу взяли browserify и довольны. Нельзя так с модулями делать, это нарушение целостности модуля, совсем не факт что модуль останется рабочим после таких изменений.

Если эта идея ради того чтобы было проще собирать клиентский код, посмотрите в сторону browserify, прекрасный инструмент

golyshevd commented 9 years ago

require() caches the source so you need to drop and "rerequire" again (which is actually happing now) so that's not so good as it seems

@tadatuta И это было сделано в common-js не чтобы всем мешало. Во-первых, в начало сборки совсем не сложно добавить штуку которая будет чистить кэши по нужным файлам (как сейчас и делается) - во-вторых, не понятно зачем это делать. Можно ведь просто к watcher который обычно используется при разработке добавить файлы шаблонов и сервер будет рестартовать и заново require-ить.

golyshevd commented 9 years ago

И еще один "за модули": когда файл шаблона - модуль, на него можно даже юнит-тест написать. Это, конечно, "высосано из пальца", я знаю что ваши тесты смотрят какой html отдается шаблоном, но все же, фишка модуля в том, что он умеет работать сам, в нативном контексте и у него есть свой локальный scope для всяких помогашек и констант

qfox commented 9 years ago

@golyshevd Не для ради холивара, но .bh.js это сначала шаблоны, а потом уже commonjs модули ;-(

golyshevd commented 9 years ago

@zxqfox Не понимаю как одно другому мешает

qfox commented 9 years ago

@golyshevd Нууу... Я тогда не вижу разницы между текущим и:

require.extensions['.bh.js'] = function (module, filename) {
    module.exports = function (bh) {
        eval(require('fs').readFileSync(filename, 'utf8'));
    };
};
golyshevd commented 9 years ago

@zxqfox почему нельзя использовать мощь модулей даже в шаблонизаторе? Шаблон - не простая программа, она имеет право быть разбитой на модули. Мне иногда кажется, что где-то думается, что шаблон не может быть нормальной js-программой, ему надо быть написанным на каком-то странном языке, главное - чтобы он отличался от js.

Я тогда не вижу разницы между текущим и:

Серьезно? Это едва годится для отладки, это мы так будем собирать bh если он лишится оберток. Конечно не так, если мы не хотим положить диск при нагрузке на сайт, но похоже как-то.

golyshevd commented 9 years ago

@zxqfox И все таки, зачем нужно придумывать какие-то костыли, если можно просто оставить все как есть? Сейчас все прекрасно жеж

qfox commented 9 years ago

@golyshevd В общем случае шаблон это преобразование одного в другое, отформатированное. Есть желание пойти в отпуск — беру формуляр, заполняю, иду в отпуск. Нужно собрать хтмл — беру файл и шаблонизатор, сую в результат данные, получаю хтмл. Если хотим собирать хтмл на морде — явно будут проблемы с кучей возможностей node.js, либо шаблоны будет распирать. Судя по browserify — require у вас в шаблонах вещь не редкая, но вы сами себе грабли раскидываете. Не надо так.

Серьезно? Это едва годится для отладки, это мы так будем собирать bh если он лишится оберток. Конечно не так, если мы не хотим положить диск при нагрузке на сайт, но похоже как-то.

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

И все таки, зачем нужно придумывать какие-то костыли, если можно просто оставить все как есть? Сейчас все прекрасно жеж

Я не настаивал на этом Issue, но сейчас я еще более убежден, что оно нужно. Потому что:

а технология для сборки клиентского BH - вообще "произведение искусства", мы как только увидели как она работает (обрезает), так сразу взяли browserify и довольны.

... И если вы используете browserify для шаблонов — явно с шаблонизатором что-то не так.

golyshevd commented 9 years ago

Судя по browserify — require у вас в шаблонах вещь не редкая, но вы сами себе грабли раскидываете. Не надо так.

... И если вы используете browserify для шаблонов — явно с шаблонизатором что-то не так.

Почему? Почему я не могу в коде использовать require? И чем плох browserify? Мне использовать очередный костыль-велосипед если я хочу сделать url.format или если я хочу использвать underscore/lodash? Правильно будет написать все хелперы руками и также вшить их в начало шаблона?

и процитирую сам себя

Мне иногда кажется, что где-то думается, что шаблон не может быть нормальной js-программой, ему надо быть написанным на каком-то странном языке, главное - чтобы он отличался от js.

UPD

Мы используем browserify только для браузерных шаблонов, мы любой шаблон можем притащить на клиент, не превращая стройные модули в груду кода. Проведу параллель - возьмем python и выпотрошим импорты - нормально будет?

tadatuta commented 9 years ago

@golyshevd вернул метку question, будем «думать еще раз» :)

golyshevd commented 9 years ago

@tadatuta Спасибо большое.

Хочу лишь сказать, что когда мы впервый раз попробовали bem-components + BH, были несказанно рады такому подходу к шаблонизатору: "наконец-то станет легко и удобно верстать", что подтвердилось:

  1. Мы собираем десяток шаблонов за 5 секунд на холодную.
  2. Всегда минимально модифицируются файлы - всякие умные IDE типа Webstorm не сходят с ума от вечно индексирующегося файла со всеми шаблонами и не вешают комп, потому что он теперь редко меняется, меняются лишь отдельные модули и его не надо игнорить в IDE.
  3. Когда шаблон роняет исключение сразу написано откуда оно выпало
  4. Одинаковая сборка как для клиента так и для сервера (для клиента собираем из deps-by-tech + полировка browserify)
  5. Мы линтуем модули по тем же правилам что и другие серверные модули
  6. Мы не ограничиваем себя в использовании других common-js модулей в шаблонах

Извиняюсь за эмоции, просто не хочется все это терять :)

qfox commented 9 years ago

Мы не ограничиваем себя в использовании других common-js модулей в шаблонах

Но зачем?

tadatuta commented 9 years ago

@golyshevd

У оберток есть 3 очевидных минуса:

  1. Неконсистентность с BEMHTML
  2. Для клиента их нужно вырезать или использовать browserify
  3. Их нужно писать

Предлагаю внимательнее рассмотреть плюсы и взвесить за и против.

Мы собираем десяток шаблонов за 5 секунд на холодную.

Тупая конкатенация вряд ли будет заметно отличаться по времени в абсолютных числах.

Всегда минимально модифицируются файлы - всякие умные IDE типа Webstorm не сходят с ума от вечно индексирующегося файла со всеми шаблонами и не вешают комп, потому что он теперь редко меняется, меняются лишь отдельные модули и его не надо игнорить в IDE.

Но и пользы от полотна рекваиров вряд ли много.

Когда шаблон роняет исключение сразу написано откуда оно выпало

Это ведь решается включением source maps?

Одинаковая сборка как для клиента так и для сервера (для клиента собираем из deps-by-tech + полировка browserify)

Как и в случае с конкатенацией ;)

Мы линтуем модули по тем же правилам что и другие серверные модули

Верно же, что после добавления нескольких глобальных переменных в конфиг линтера, все проблемы исчерпываются?

Мы не ограничиваем себя в использовании других common-js модулей в шаблонах

С поправкой на то, что модули должны быть кроссплатформенными и вам требуется browserify.

Мы же исходим из предположения, что и на клиенте и на сервере есть ym.

qfox commented 9 years ago

Одинаковая сборка как для клиента так и для сервера (для клиента собираем из deps-by-tech + полировка browserify)

@golyshevd Где ж она одинаковая, если для клиента через browserify?

Когда шаблон роняет исключение сразу написано откуда оно выпало

С тем кодом, что я предложил, можно тоже ронять с указанием места в коде. К чему паника?

вернул метку question, будем «думать еще раз» :)

@tadatuta Я лично не вижу проблем со всем перечисленным, если убрать в bem-components обертку. Собирать в dev режиме можно будет точно так же, как и раньше через require. В продакшн режиме — склейка с обрезанием, либо просто склейка, либо еще что-то (browserify?). Да и здесь все равно речь только о bem-components, где никакой url.format не возможен в шаблонах даже теоретически. Еще можно подумать про суффикс bh вместо bh.js. dixi.

golyshevd commented 9 years ago

зачем?

@zxqfox А зачем делать себе подобные ограничения в коде который исполняется преимущественно в nodejs среде? BH это всего-лишь библиотека, тот же модуль. И он должен быть интегрируемым в другие модули. Мой шаблон - модуль, он использует внутри себя BH как модуль.

BH не навязывает стиля написания шаблонов, и это прекрасно, а bem-components потенциально может это сделать. Как вообще библиотека может ограничивать возможности платформы? Беру bem-components - теряю модули?

@tadatuta

  1. Неконсистентность с BEMHTML

В чем? BEMHTML - это вообще не js. Если речь о BEMHTML который js-ный то не понимаю в чем неконсистентность. В том что у него нет обертки? это разные шаблонизаторы, как можно сравнивать их код?

  1. Для клиента их нужно вырезать или использовать browserify.

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

  1. Их нужно писать

Ну тут даже не знаю что ответить, код нужно писать чтобы он был.

Тупая конкатенация вряд ли будет заметно отличаться по времени в абсолютных числах.

Согласен, этот пункт я присвоил нечестно, это я сравнивал с BEMHTML который компилируется "неделю".

Мы же исходим из предположения, что и на клиенте и на сервере есть ym.

Это отдельная тема для разговора, но зачем на сервере ym если на сервере есть common-js?

@zxqfox

Где ж она одинаковая, если для клиента через browserify?

Это лишь дополнительный слой, browserify лишь создает common-js среду. Сам код не изменяется, появляется только обертка, в которой реализована require умеющая импортить лишь нужные модули из этого же файла.

С тем кодом, что я предложил, можно тоже ронять с указанием места в коде. К чему паника?

Это прокатит только в development, в production будет совсем другой код который может работать иначе.

Но и пользы от полотна рекваиров вряд ли много.

Как же нет пользы, код разбит на модули, нет лишней кодогенерации. Вреда точно нет. Если и есть проблема какая-то с require, то это проблема nodejs а не bem-components.

Это ведь решается включением source maps?

Но ведь можно и без него?

Одинаковая сборка как для клиента так и для сервера (для клиента собираем из deps-by-tech + полировка browserify)

Как и в случае с конкатенацией ;)

Тут вообще никакой разницы, просто другая тенология для сборки, в обоих случаях ничего не надо делать, но в случае c browserify мы перекладываем ответственность на поломку модульности на него, и он гораздо комплекснее подходит к эмуляции модулей

Верно же, что после добавления нескольких глобальных переменных в конфиг линтера, все проблемы исчерпываются?

Надо для шаблонов делать отдельный конфиг, чтобы писать в strict mode нельзя писать use-strict в начале файла. Надо всегда понимать что этот кусок кода не является самостоятельной программой. В моем случае вообще ничего не надо делать, каждый файл - нативный модуль и всем хорошо

С поправкой на то, что модули должны быть кроссплатформенными и вам требуется browserify.

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


Я не выдержу вашего напора скоро. Я просто не понимаю проблем, которые вы решаете. Сейчас у нас есть работающий модульный код. Его легким движением можно превратить в работающий на клиенте. С модулями вы можете делать ваши шаблоны гибче, круче, вы можете даже package.json класть в каждый блок если захотите (это фантастика, но модули дают много возможностей), вы можете использовать url.format а не 'foo=' + escape(bar) + '&baz=' + escape(zot).

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

Это все ради того чтобы было удобнее собирать код для браузера и не использовать существующие решения? И чтобы не писать module.exports = ?

Даже если вы это сделаете, мы, конечно выкрутимся, мы все равно сгенеренный код будем browserify-ить, но неужели вы не видите очевидных преимуществ?

qfox commented 9 years ago

Это лишь дополнительный слой, browserify лишь создает common-js среду. Сам код не изменяется, появляется только обертка, в которой реализована require умеющая импортить лишь нужные модули из этого же файла.

Это хаки и лишний код на клиенте. Кому-то это ок, кому-то нет. Сейчас получается, что одни обрезают module.exports, другие — прогоняют через browserify. В чем логика?

qfox commented 9 years ago

вы можете использовать url.format а не 'foo=' + escape(bar) + '&baz=' + escape(zot).

На мой взгляд это вообще не должно находится в шаблонах. Если это складывать в шаблоны — они начинают слишком дохрена знать про внутреннюю логику приложения и связываются с тем кодом, который будет разбирать этот foo=baz. Логичнее генерировать эти урлы заранее и подавать на вход шаблонизатору, чтобы «модуль» шаблона делал только свое дело, а урлы для него генерировал другой код.

qfox commented 9 years ago

Беру bem-components - теряю модули?

Не вижу связи, но может быть проблема в сборщике, а не в формате шаблонов.

qfox commented 9 years ago

Я не выдержу вашего напора скоро.

Нет уж, давай разбираться до конца ;-)

golyshevd commented 9 years ago

Это хаки и лишний код на клиенте. Кому-то это ок, кому-то нет. Сейчас получается, что одни обрезают module.exports, другие — прогоняют через browserify. В чем логика?

Лишнего кода там очень мало.

Примерно вот столько в начале:

!function t(e,n,i){function o(s,u){if(!n[s]){if(!e[s]){var c="function"==typeof require&&require;if(!u&&c)return c(s,!0);if(r)return r(s,!0);var a=new Error("Cannot find module '"+s+"'");throw a.code="MODULE_NOT_FOUND",a}var l=n[s]={exports:{}};e[s][0].call(l.exports,function(t){var n=e[s][1][t];return o(n?n:t)},l,l.exports,t,e,n,i)}return n[s].exports}for(var r="function"==typeof require&&require,s=0;s<i.length;s++)o(i[s]);return o}({1:

И совсем капельку для каждого модуля (несколько символов).

Если сравнивать два хака - browserify и объединение скоупов модулей в один, то первый, очевидно гораздо безопаснее. Во втором случае, если в глобальных скоупах разных модулей будет одинаковая переменная, то долго будем отлаживать шаблоны.

По поводу того, что все собирают как хотят - спасибо ENB что он позволяет нам выбирать хаки на вкус и цвет. Не думаю что bem-components хочет нести ответственность за что что ее неправильно скомпилируют.

На мой взгляд это вообще не должно находится в шаблонах

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

Не вижу связи, но может быть проблема в сборщике, а не в формате шаблонов.

Мне не нравится что итоговый шаблон - common-js модуль, который компилируется из другого рода модулей (не common-js), которые могут в свою очередь зависить от нормальных модулей. А цена всего этого лишь module.exports, который мне надо будет при сборке "дописывать". Тут, как я понимаю действует минусующий модули пункт про то что "надо писать module.exports". Так я вот что скажу, когда в библиотеке появится сложный шаблон и захочется сделать функцию хелпер, то все равно придется делать...

(function () {
    function helper() { ... }
    bh.match(..., function () {
        helper()
    });
}());

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

qfox commented 9 years ago

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

bh.lib.helper ? https://github.com/bem/bh/blob/master/lib/bh.js#L33-L42

golyshevd commented 9 years ago

bh.lib.helper

Ну, по мне, так это семантически подойдет для каких-то абстрактных штук, примеры там в комментах. Я же говорю о какой-нибудь погремушке типа createUserPicForBlahBlahListItem() которая будет иметь смысл только для какого-то конкретного шаблона. Несомненно, это можно использовать и для локальных хелперов, но тогда остается риск опять же пересечься, потому что этот объект статический. Мне сложно сейчас выдать пример, библиотечные шаблоны обычно проще пользовательских и достаточно атомарные и интегрируемые.

remnev commented 9 years ago

Ребят, Дима привел шквал аргументов, почему мы любим bh-шаблоны такими, какие они сейчас. Мне кажется мы одна из немногих команд, кто использует bem-components внутри компании. И мы просто влюблены в нее с первых дней. Так сильно, что пропагандируем ее везде вокруг себя. Давайте прислушиваться к мнению потребителей (т.е. и нас в том числе), особенно если они аргуметированы.

voischev commented 9 years ago

Мне пока нравится что пишет @zxqfox

tadatuta commented 9 years ago

@remnev Дима привел 6 аргументов против моих 3. В обсуждении мы выяснили, что половина из них на самом деле на аргументы не тянет.

Уже двое активных пользователей тоже высказались против оберток.

Предлагаю попробовать поискать решения, которые устроят всех.

Ну, например, можно ведь руками писать без оберток и заворачивать в common-js во время сборки, если это действительно имеет смысл. При этом появится опциональная возможность на клиент отдавать as is. Или тоже заворачивать. Или еще какие-нибудь варианты придумать.

qfox commented 9 years ago

Ребят, мне сейчас больше всего не нравится, что как ни крути — файлы надо готовить. Мы не можем что-то придумать, чтобы их не надо было готовить хотя бы для какого-то использования? Либо же, писать шаблоны так, чтобы в них было минимум полезной информации и не приходилось подрезать и колдовать с ними.

Например, я не вижу ничего сатанинского в написании обертки для .bh.js и размещения в require.extension. Без eval, конечно. Все те возможности, которые есть сейчас, останутся (в т.ч. указание строки, кеширование, подключение через require как модулей, etc.). Для продакшна — все равно придется их собирать.

И еще: вариант про .bh без обертки и .bh.js с оберткой — совсем не нравится?

qfox commented 9 years ago

Я же говорю о какой-нибудь погремушке типа createUserPicForBlahBlahListItem() которая будет иметь смысл только для какого-то конкретного шаблона.

@golyshevd А это, имхо, должно быть в bemtree или priv.js. В общем, неважно ;-)

golyshevd commented 9 years ago

И еще: вариант про .bh без обертки и .bh.js с оберткой — совсем не нравится?

Это вариант, странный, но вариант.

А это, имхо, должно быть в bemtree или priv.js. В общем, неважно ;-)

Лично я считаю что privjs - это вынужденный костыль для BEMHTML (того который первый), без которого он абсолютно немощен, мы не почувствоали необходимость использовать privjs вместе с BH, потому что он - нормальный js, в котором можно вполне безобидно генерить контекст.


Вобщем, я буду повторять, но все же, я задам вопрос снова. Почему му не хотим писать module.exports ?

У нас сейчас два противоположных мнения:

  1. Ничего не делать с серверными шаблонами, оставив их валидными программами, и ничего не делать с клиентскими шаблонами, лишь изменить их сборку (browserify) (Я это мое мнение + @remnev)
  2. Переписать все серверные шаблоны, сделав их невалидными программами, превратив их в куски кода, и изменить сборку как клиентского кода, так и серверного, получив выгоды лишь в скорости написания шаблонов. (Это ваше мнение)

Я прав?

Давайте расставим точки над I, насчет чего мы спорим?

UPD я несколько раз переписал пост потому что я в отпуске, не всегда с первого раза получается, простите

qfox commented 9 years ago

Давайте расставим точки над I, насчет чего мы спорим?

@golyshevd Насколько я понял, вы шаблоны используете как модули, в т.ч. с содержанием какой-то бизнес логики, и вопрос именно в этом. Это не плохо и не хорошо, просто это уже не шаблоны, или не просто шаблоны, это js модули с шаблонами внутри.

upd

получив выгоды лишь в скорости написания шаблонов. (Это ваше мнение)

Я прав?

т.е., нет. ;-) У нас просто разный взгляд на .bh.js файлы (возможно и на шаблоны вообще).

На мой взгляд, в этом случае есть смысл именно разделять .bh.js на 2 разных подхода: будет это bh и bh.js или как-то еще — обсуждаемо.

qfox commented 9 years ago

@golyshevd Вообще, странно, что еще не прозвучало: «Простое — просто, сложное — возможно», потому что речь и про это тоже.

Если разделять, была похожая идея про bemhtml и bemhtml.js, и там суффикс js играет немного иначе, ставится противопоставление двух синтаксисов: block link, tag a vs block('link').tag()('a'). #1464 Т.е. один — кастомный синтаксис, второй — валидный js с кучей глобальных функций (переменных). В этом случае, для консистентности .bh.js лучше переименовать в .bh.common.js или .bh.node.js, или как-то так, но кажется, что это совсем бред.

У меня еще такой вопрос: вас не устраивает двухпроходность или вы не видите в ней целесообразности? Контекст ведь можно генерировать и в bh, не обязательно для этого использовать privjs, просто делать это отдельным проходом с отдельными match'ерами.

golyshevd commented 9 years ago

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

Вовсе нет, смотря что ты называешь бизнес логикой. Вот смотри, табличечка (Это не BH но не суть) https://contest.yandex.ru/algorithm2013/contest/308/standings/, она совсем не простая, в шаблон приходит вполне определенная модель данных, но все равно в шаблонах не всегда можно обойтись только одними предикатами. В целом - это очень сложная страница, но ее вид определен еще на сервере, хотя варивантов ее отображения - бесконечно, поэтому часть логики шаблонизации, конечно есть в шаблонах (if, switch). Мы немного задумываемся о том, как нормально писать сайты, мы же не просто, простите, фигачим, поэтому, считаю неуместными намеки, на то, что все должно быть не так, а вот так.

Я не зацикливаюсь на том, что нам нужны модули, потому что мы не умеем без них, я говорю о том, что модули, это не плохо, их бояться не надо, и я до сих пор не усолышал убедительных оправданий придумать новый язык программирования, модули дают большой набор возможностей и никого ни в чем не ограничивают. Вы же хотите сделать работы больше раза в 3 чем я предлагаю сделать (всего лишь продумать client-bh компилятор) просто ради того, чтобы не писать module.exports и ограничить разработчиков в их вохможностях. Хотя, уверен, что опуск module.exports не сэкономит много времени при разработке сайта, который состоит более чем из 3 блоков.

вас не устраивает двух проходность или вы не видите целесообразности?

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

Но второе, да, целесообразность. Вы можете как то выразить что и насколько станет лучше, когда вы уберете все обертки module.exports ? Мы то выкрутимся и даже если на не отпустит, мы все равно сделаем так как хотим. Но вам придется:

  1. Переписать все шаблоны
  2. Переписать все тест-тулы
  3. Напрячь всех пользователей изменив формат радикально и так и не обосновав зачем.
  4. Вызвать странные вопросы (я тут один нервничаю, потому что, на самом деле, скорее всего, и правда, пользователей по пальцам сосчитать)
  5. <и тд.>

Я же просто говорю - продумайте как лучше сделать сборку браузерного шаблона, зачем переделывать все?

qfox commented 9 years ago

она совсем не простая, в шаблон приходит вполне определенная модель данных

Я по этому поводу на днях статью публиковал, если в отпуске — было бы здорово услышать критику двухпроходной шаблонизации ;-) https://medium.com/@qfox/34d55e3b8dfd Т.е., если надо все переиграть — это не должно происходить в шаблоне, шаблон должен вью-ориентированную структуру переиграть в html. В т.ч. тот же формат урла, который генерируется во вью — это часть бизнес логики, которая, на мой взгляд, не должна лежать в шаблоне, потому что шаблон ничего не знает про этот урл. У него на входе — bemjson, на выходе — html.

Хотя, уверен, что опуск module.exports не сэкономит много времени при разработке сайта, который состоит более чем из 3 блоков.

Еще раз повторю, что дело далеко не только в этом. @tadatuta уже описал что было взвешено, и разницы никто не увидел.

я говорю о том, что модули, это не плохо, их бояться не надо

Могу сказать со 100% уверенностью, что смысл module.exports не ясен в контексте шаблонизатора, хотя и понятен с точки зрения common-js модуля. Что именно это означает для шаблона? Когда приходит человек в команду — как ему объяснить, что это нужно без: «Просто бездумно делай так», — особенно если он верстальщик, и js знает совсем немножко? А самое главное — зачем это делать? В любом случае, даже если согласиться с этим — доносить это нужно не до нас, а до сотен тысяч верстальщиков.

и я до сих пор не усолышал убедительных оправданий придумать новый язык программирования

Язык программирования все тот же — js. Если из такой точки зрения исходить — то и формат тестовых файлов mocha это новый язык программирования.

Я же просто говорю - продумайте как лучше сделать сборку браузерного шаблона, зачем переделывать все?

Я правильно понимаю, что проблема в желании иметь некий scope, в котором можно будет регистрировать какие-то хелперы, используемые в шаблонах? Потому что, отчасти это мешает «продумать» сборку — bh так устроен, что запускается и выполняется в рантайме, это дает возможность прокидывать внутрь матчеров скоуп модуля. Не знаю, предполагалось ли его так использовать, но чтобы эту возможность оставить — я пока не вижу других вариантов, кроме:

(function(){
  var module = {};
  /*bhmodule*/
  module.exports(bh);
}());

Т.е. когда кто-то обрезал сверху module.exports — они явно не думали, что там кто-то будет переменные внутри писать и после использовать.

Ну и я все больше убеждаюсь, что вы используете bh не так, как расчитывалось. Хочу еще послушать иницииаторов, на самом деле.

tadatuta commented 9 years ago

@golyshevd Я уже писал о том, откуда желание отказаться от оберток: https://github.com/bem/bem-components/issues/1286#issuecomment-99261921, причины три.

Предлагаю чуть внимательнее разобрать список проблем, которые это за собой влечет:

1) Переписать все шаблоны

Обертка же одинаковая, это простой search'n'replace в файлах *.bh.js.

2) Переписать все тест-тулы

Все тест-тулы, которые мы используем и всем рекомендуем никак переписывать не придется — прямо сейчас можно писать как с, так и без оберток.

3) Напрячь всех пользователей изменив формат радикально и так и не обосновав зачем.

Для тех пользователей, которые используют bh-server-include.js для сборки это полностью обратносовместимое изменение. И, как я уже писал, в треде участвуют пользователи, которым нравится идея отказа от оберток.

Вызвать странные вопросы (я тут один нервничаю, потому что, на самом деле, скорее всего, и правда, пользователей по пальцам сосчитать)

Давай попробуем вместе найти на них понятные ответы. Судя по статистике внутренних пользователей BH примерно 35% от всех пользователей Islands, так что, вроде как, есть кому переживать, если это действительно проблема.

golyshevd commented 9 years ago

@zxqfox

Я по этому поводу на днях статью публиковал, если в отпуске — было бы здорово услышать критику двухпроходной шаблонизации ;-)

В отпуске один раз только был интернет. Но почитаю статью, спасибо.

У него на входе — bemjson, на выходе — html.

Сто раз об этом думал, где грань в которой пересекаются BEMHTML и BEMTREE/privjs. Получается в bemhtml только теги надо расставлять? Мы долго философствовали на эту тему и продолжаем думать. Один проход просто избавляет от этих мыслей. Но вообще ничего не имею против такой шаблонизации, писали на xslt. Сначала data->view, потом html. Но там нельзя контекст достраивать дешево. А тут можно делать шаблон и тут же строить контекст для потомков дерева. Так даже проще, хотя идеологически может и не так красиво.

Могу сказать со 100% уверенностью, что смысл module.exports не ясен в контексте шаблонизатора

А вот мне почему-то кажется наоборот, когда я вижу модуль, экспортирующий функцию, я гораздо быстрее врублюсь откуда ноги растут, я знаю что я могу делать с модулем и как и использовать. А если я увижу косок кода, то я конечно догадаюсь что он куда-то "вклеивается", но куда, и какие у меня будут возможности, что мне можно и что нельзя, а если я переменную глобальную потру или сломаю?

Когда приходит человек в команду — как ему объяснить, что это нужно без: «Просто бездумно делай так», — особенно если он верстальщик, и js знает совсем немножко?

Я вот, не верю что существуют такие люди, этакие матерые цээсэсеры, которые не знают js. Другое дело node, да, но что common-js понять не надо быть семи пядей во лбу, те кто имеют дело с js, уверен, слышали что это такое.

Язык программирования все тот же — js. Если из такой точки зрения исходить — то и формат тестовых файлов mocha это новый язык программирования.

Вот! У mocha есть интрерпретатор! У bh - нет, bh просто либа, которая дает скомпилить в памяти шаблон и выполнить его потом. Вот есть еще такой зверь jade - тоже в коробке есть штука, которая выполняет шаблоны. А BH крут тем что это библиотека на чистом js и интерпретатором ему даже голый V8 наверно подойдет. И использовать его можно по-разному. Вот мы и спорим, потому что вам думается так, а нам эдак.

И вот, у нас есть два решения.

  1. Убрать везде обертку module.exports и тогда на клиенте и на сервере будет одинаковая сборка.
  2. Не убирать нигде module.exports но для клиентского шаблона еще делать browserify.

Почему мне нравится второй вариант больше. Потому что браузер и нода, как ни крути - окружения разные, и нет никакого греха компилировать сырцы для них по-разному. Но сырцы должны быть удобоваримые и максимально удобными для компиляции во что угодно. И дополнительный шаг компиляции для браузерного кода выглядит очень даже стройно, никакой магии, никаких сложных технологий. А вы хотите просто склеить все файлы добавив в начало шаблонизатор, еще все файлы придется "обмотать" в функцию чтобы скоуп у модуля был.

я пока не вижу других вариантов, кроме:

И мы так и будем делать, если не сможем вас переубедить.

Ну и я все больше убеждаюсь, что вы используете bh не так, как расчитывалось.

А как рассчитывалось? Мы сталкиваемся в том, что вы закрываете глаза на те ограничения, которые вводите тем, что хотите придумать свой формат модуля, который не так функционально хорош как common-js модуль. Сам BH ничего не навязывает. Его можно использовать как угодно. Фактически мы просто обсуждаем "как будем писать сырцы".

Я говорю - давайте писать понятные сырцы и немного ипрувнем сборку, причем, вместе с этим выдадим пользователям абсолютно безграничные возможности. А вы говорите - давайте писать шаблоны так, будто они уже скомпилены, а компилятор их просто склеит.

@tadatuta Ладно, давайте разберем плюсы того что вы хотите сделать

У оберток есть 3 очевидных минуса:

  1. Неконсистентность с BEMHTML

Тут нужно пояснение, не понимаю причем тут BEMHTML

  1. Для клиента их нужно вырезать или использовать browserify

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

  1. Их нужно писать

Вот это я не приму, тут тоже нужна какая-то цифра, которая объяснит насколько сложно/дорого писать каждый раз эту строчку кода. В IDE можно делать шаблоны файлов в конце концов.

Давай попробуем вместе найти на них понятные ответы.

Здорово что есть инструменты, которые позволят не переписывать все шаблоны если я обновлюсь до нового bem-components. Это все что я могу сказать.

golyshevd commented 9 years ago

PS: Мне все больше начинает казаться что вопрос для меня становится все более просто принципиальным, однако, я по прежнему уверен, что решение, которое я предлагаю, не сложнее вашего. Осовенно тем, что для его реализации не нужно делать ничего. С текущим форматом шаблонов уже живут пользователи. Кто то вырезает, кто-то browserify-ит, но весь код уже написан

qfox commented 9 years ago

А вот мне почему-то кажется наоборот, когда я вижу модуль, экспортирующий функцию, я гораздо быстрее врублюсь откуда ноги растут, я знаю что я могу делать с модулем и как и использовать

Только ведь в него нужно передать какой-то контекст — т.е., без доп. работы все равно не обойтись. Это все равно доп. знания, даже если по commonjs в виде модуля шаблон написан.

Вот! У mocha есть интрерпретатор! У bh - нет, bh просто либа, которая дает скомпилить в памяти шаблон и выполнить его потом

Ну, это спекуляция ;-). Если сделать, условно, global = mocha и запуск деклараций в конце, то все остальное будет работать. Т.е. моке нужен такой же бутсрап, как и bh. Разница лишь в том, что для моки мы что-то в глобал напишем (или через vm запустим), а тут явно передим, и vm мы запустим через модуль ноды: https://github.com/nodejs/io.js/blob/master/lib/module.js#L411-L414 — т.е. разница в самом бутстрапе. Но это никак не интерпретатор отдельный, имхо.

А BH крут тем что это библиотека на чистом js

Сама библиотека BH и его шаблоны — это несколько разное. Впрочем, это не самое важное.

и нет никакого греха компилировать сырцы для них по-разному.

;-) Все-таки компилировать?

А как рассчитывалось?

Судя по отсутствию критики — я в статье сделал мало ошибок по этому поводу. Можно продолжить после ознакомления :smirk_cat:

Но, повторюсь, хоть разница и принципиальная, это не значит, что исчезнет возможность писать шаблоны, как вы сейчас пишете, на своем уровне. Другое дело — библиотеки, и я предлагаю использовать другой суффикс — в этом случае ?.bh мы будем просто склеивать и после оборачивать (сорс мапы простейшие), а ?.bh.js — как сейчас.

golyshevd commented 9 years ago

Только ведь в него нужно передать какой-то контекст

Данные? Ну конечно, но это не касается модуля, данные обрабатываются при вызове шаблона, а мы говорим про определение.

Разница лишь в том, что для моки мы что-то в глобал напишем (или через vm запустим), а тут явно передим

Явное всегдя лучше неявного. Мне лично это важно. Про моку скажу, что тоже не понимаю зачем там сделано так, мне дизайн не нравится.

;-) Все-таки компилировать?

Я имел ввиду из кучи модулей сделать один единственный, который будет являться шаблонизатором. Для сервера одним способом, а для бразера таким же, но чуть продвинутым.

и я предлагаю использовать другой суффикс

Это меня лично устроит и успокоит, то есть фактически ничего не изменится, появятся лишь новые файлы *.bh без обертки, которые я не буду использовать, это ок и вполне логично

Можно продолжить после ознакомления

Завтра обязательно прочитаю, сейчас сил нет, увы =(

qfox commented 9 years ago

Данные? Ну конечно, но это не касается модуля, данные обрабатываются при вызове шаблона, а мы говорим про определение.

Не данные, а библиотеку, которая соберет эти шаблоны в функцию: bh.match + bh.apply.

Явное всегдя лучше неявного.

CommonJS — такое же «явное», я привел ссылку на то, как это работает. Так что, не аргумент.

мне дизайн не нравится.

Не аргумент ;-) Это субъективно.

которые я не буду использовать, это ок и вполне логично

Если сейчас не нужна bem-components, то о чем вообще спор?