У нас на проекте для фронта используются bem-components, а серверной частью занимается Symfony и шаблонизатор Twig. Возникла совершенно не понятная проблема с инициализацией бэм скриптов, если шаблонизатором Twig создавать копии js файлов (или объединять) на стороне сервера, что-бы выдавать пользователю свежие скрипты.
Работает создание копий на деве и объединение всё в один файл на бою в твиге так:
{% javascripts
'@jquery'
'plugins/modernizr/modernizr.js'
'plugins/bem-components/desktop/bem-components.js+bh.js'
'js/common.js'
output='js/compiled/app.js'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
В итоге, к примеру для дева, создаются копии файлов всех перечисленных скриптов с новым названием, что избавляет от проблем кэширования, т.е. на фронте скрипты выглядят уже так:
<script src="/app_dev.php/js/compiled/app_part_1.js"></script>
<script src="/app_dev.php/js/compiled/app_modernizr_2.js"></script>
<script src="/app_dev.php/js/compiled/app_bem-components.js+bh_6.js"></script>
<script src="/app_dev.php/js/compiled/app_common_7.js"></script>
И вот здесь уже возникает не понятная проблема, все скрипты с идентичным исходным кодом, как в оригинале, просто загружаются из другой папки с другими названиями, но с вероятностью 50% БЭМ модули не отрабатываются и не инициализируются. Причем скрипты все загружаются, в правильном порядке, в консоли чисто, ни одной ошибки, просто модули не инициализируются. jQuery код нормально отрабатывает, а вот БЭМ просто молчит. Кто сталкивался с данной проблемой? А то мне уже надоело выслушивать сопли бэкендеров, что бэм такой сякой и дело не в твиге, а в бэме и т.д. и т.п., динозавры они короче говоря, привыкли по старинке ваять кучи непонятного jQuery кода и теперь всё остальное для них, это бред и их мнение истина)) Ну думаю некоторые поймут)
PS: если подключать обычным способом, то все нормально работает.
Как вызвать init всех модулей когда мне это нужно, в случае подгрузки модулей асинхронно к примеру? или на подобии jQuery, сделать проверку для инициализации написанных мной модулей?:
Вместо
bem-components.js+bh.js
нужно братьbem-components.no-autoinit.js+bh.js
(https://yastatic.net/bem-components/latest/desktop/bem-components.no-autoinit.js+bh.js)И тогда запускать инициализацию руками:
Ок, а если модуль подгружается динамически, после того, как все все остальные модули уже один раз инициализировались, могу я вызвать повторную инициализацию?
Раз уж наш Кадавр помянул меня тут всуе, то уточню в чём проблема. Когда в "bem-components.js+bh.js" (не спрашивайте зачем он его принёс, понять что он делает он всё равно не в силах, но именно этот вариант кто-то в примерах упомянул, а наш сорванец тащит в проект всякую гадость =) происходит инициализация через nextTick в реализации из "i-bem__dom_init_auto.js", то модули подгружающиеся из отдельного файла периодически ещё не успевают зарегистрироваться в modules, хотя DOMContentLoaded уже отработал и всё понеслось (проблема наблюдается как Firefox под Linux, так и в Chrome на OS X). В результате modules.getState() выполненный потом в консоли возвращает нам наши модули из common.js в списке NOT_RESOLVED. common.js отдельно не доступен, но он в конце http://www.ucheba.live/js/compiled/app.js начинаясь с объявления 'fsv-info-switcher'.
Исправьте по возможности сей косяк или объясните нашему Кадавру что не надо использовать ради того что он реализует 154 КБ непонятного ему кода.
Заранее спасибо =)
P.S.: Граждане! Вас читают дети! Когда указываете в примерах какой-либо вариант сборки указывайте зачем, а то они переписывают за вами код в проект не понимая что он делает, а потом с пеной у рта доказывают что проблемы в Twig - он даже на понимает как шаблонизатор работает и что он не отвечает за доставку кода common.js (впрочем он вообще мало что понимает, за это его и любим 8)
@sryabov, ну вот почему сразу гадость-то? ;)
Мы ведь пишем: «Important: If you're going to write your own code with i-bem.js you must use bundles without autoinit and call initialization manually.»
Или вот по-нашему: «Бандлы с автоинициализацией используются, если вы НЕ планируете добавлять собственный код на i-bem.js».
Так что сей косяк по классике является не багой, но фичей. И все возможности для того, чтобы с этой фичей нормально жить, заблаговременно предоставлены.
Про необходимость использования всех 154 КБ не могу ответить, не зная как код используется. Но на всякий случай расскажу, что если на проекте не используются готовые компоненты из https://ru.bem.info/libs/bem-components/ или не используется клиентская шаблонизация на BH, то можно подобрать сборку на свой вкус без первого, второго или исключить оба пункта. Размер заметно уменьшится.
Если же все это используется, то странно ожидать, что это не потребует некоторого количества байтиков. Кстати, мы предлагаем их подключать с распределенного CDN, отдающего файлы с вечным кэшированием. Все для вас.
Ну и, наконец, если хочется еще большего контроля, можно собирать бандлы четко под свои нужны, туда будут входить лишь нужные блоки, только нужные их элементы, нужные модификаторы и ни байтика лишнего.
Готов лично всячески содействовать, только бы вопросы правильные формулировались. А решений есть у нас на любой вкус и цвет. И они норм, даже Пепелсбей одобряет ;)
В общем случае повторная инициализация на уже проинициализированном куске DOM-а невозможна, но с большой долей вероятности тебе этого не нужно :)
Расскажи подробнее, что именно происходит и какие задачи хочется решить, чтобы не угадывать с решением. Не только в терминах, что конкретно не работает, но и в высокоуровневых терминах — откуда такие желания возникают.
Ну что поделать - карма у него такая =). У меня уже реакция - всё что он притащил гадость, потом может и пойму в чём цимес. Но пока я только проблемы разгребаю, но это не благодаря вам, а благодаря нашему одарённому Кадавру - документации же читать мы не обучены, да ещё и динозавры его соплями залили =).
Кстати еще жалоба - маркетинг это конечно хорошо, но надо разработчикам давать прямой доступ к документации с главной страницы и не писать её языком минобра с использованием слова МЕТОДОЛОГИЯ (сразу вызывает отвращение =).
Я честно тоже не хочу знать что он там использует, но уверен что и половины не использует. Но как говорится - чем бы дитя не тешилось, лишь бы не руками. В этом проекте я отдал ему фронт на полное растерзание (я честно не хотел туда вообще влезать), а он от меня в результате просит противоествественного - вставлять костыли в код из-за своего нежелания документацию читать =).
Тогда попробую более абстрaктно и практично задать вопрос в двух вариантах.
<script async>
, то как быть с инициализацией (мы же не в курсе кто из них последним загрузится)?2 .Есть страница на которой уже прошла инициализация. Мы погружаем дополнительный модуль (HTML код разумеется тоже) - как его инициализировать не повторяя волшебный функционал initBlocks из 'i-bem__dom' по вызову initBlock?
Это я всё пытаюсь понять как наше чудо может сделать модульный (загружаемый по необходимости), а не монолитный js код для всех возможных модулей страницы (я надеюсь я правильно называю модулем то что создается через modules.define). Или i-bem вообще не об этом и не следует его для этого пытаться применить?
Серега, тише, тише, не рычи взрослый ты наш, выпей чаю с ромашкой. Отвечу тебе: когда проект с нуля надо сделать за неделю и всю вёрстку с фронтом делает 1 человек, то нет возможности изучить новую технологию за эту же неделю и внедрить её на хорошем уровне, по-этому, все постепенно, исправляя косяки и разбираясь что да как. Тогда возникнет вопрос, зачем же тогда вводить эту новую технологию? Отвечу коротко: "Движение - жизнь".
Влидимир, по поводу вашего вопроса: конкретной задачи, как таковой нет, скорее проблема, которая возникла после пропускания подключаемых js файлов через шаблонизатор Twig. Если подключить скипты на страницу обычным, стандартным способом, то все работает, но если эти скрипты передавать в Твиг, что-бы он создал для них новые линки и избавил от проблем с кэшированием js кода, то уже на странице они видимо грузятся не совсем обычно, так как результат загрузки того же файла с модулями оказался похож на загрузку асинхронного кода, из-за чего инициализациях модулей, вызываемая автоматически, происходит раньше необходимого и они не инитятся. Решить эту проблему можно, либо сделать канкотинацию бэм фреймворка и наших модулей до того, как они будут переданы твигу, либо подключив версию фреймворка без автоинита и заинитить их когда надо. Но Серега, предположил различные ситуации, когда это не поможет, к примеру если подгрузить код модуля уже после того, как мы инитнули все модули, в общем он хочет докопаться до истины и либо что-то выяснить, либо что-то доказать.
АААААА!!!! Извините. =)
@Jekins Артём, ты опять пишешь абракадабру. Если ты не словил ошибку - это не значит что её нет. Тебе уже дали ответ на вопрос об объединении или не объединении скриптов: «Бандлы с автоинициализацией используются, если вы НЕ планируете добавлять собственный код на i-bem.js». Не пиши больше про Twig (ещё раз - он вообще тут не участвует, не позорься хотя бы =). Не следовало использовать тот бандл что ты притащил и точка. Нет, конкатинация тебе не поможет (если ты не ловишь ошибку, это не значит что нет проблемы) - читай ответ https://ru.bem.info/forum/1045/#comment-227584974 до просветления и выше приведенную из него цитату. Я уже спросил максимум что можно спросить про загрузку дополнительных модулей, но боюсь ты мои вопросы всё равно не понял, но я тебе потом объясню.
Извините ещё раз, он у нас такой волшебный, а я сегодня в весёлом настроении духа =)
P.S.: Кадавр, не отвлекай людей от серьезного разговора =)
Тут вот какое дело: с одной стороны БЭМ — это примерно как ООП, т.е. не про то, что можно скачать и запустить, а подход/паттерн/методология/вот-это-все, а с другой — набор из JS-фреймворка, шаблонизатора, библиотек с готовыми блоками и прочим инструментарием. Так что вывалить это все одновременно на главную страницу хотя и возможно, но не очень осмысленно.
Разделение на 4 принципиально разных подраздела пока кажется наиболее удачным способом подачи.
Первым обязано загрузиться ядро, тут вариантов нет. А последующие файлы можно асинхронно параллельно грузить, например, с помощью https://ru.bem.info/libs/bem-core/v2.8.0/desktop/loader/ и дожидаться, когда все загрузится, скажем, по
Promise.all()
.Примером того, как это работает, служит автоматическая асинхронная загрузка jQuery, если она не была предоставлена каким-то другим образом: https://github.com/bem/bem-core/blob/v3/common.blocks/jquery/jquery.js
Если речь идет о том, что проинициализировать нужно именно новый дозагруженный HTML, то с этим проблем нет: https://ru.bem.info/libs/bem-core/v2.8.0/desktop/i-bem/jsdoc/#jsdoc-init-1 + есть хелперы про манипуляцию с DOM, которые помимо собственно append/prepend/replace/update заодно и инициализируют новые узлы.
@tadatuta
Так и не надо валить всё - есть несколько ЦА для которых и должны быть точки входа (благо в вашем случае они достаточно чёткие). Те кто не знаю что такое BEM (методон и всё такое), те кто знают и ищут конкретный ответ на конкретный вопрос (документация по стилю/реализациям конкретных бандлов/cookbook), те кто ищут абстрактный ответ (форум и что там ещё). Как вариант схлопнуть инструментарий и платформу (прям страшно становится) в один пункт если больше 4х не лезет =). Просто то что документация скрывается в пункте "Сообщество" как ближайший маршрут - совсем не понятно. А это наводит на размышления о запутанности всех остальных реализованных решений ;) Ели бы еще и поиск по форуму был в рамках форума, а не с отсылкой куда-то туда с поиском по сайту, особенно на проекте связанном с Яндекс - совсем было бы хорошо =)
Да, это важно, а то не все участники опять поймут ;)
То есть обычным
<script async>
уже не обойтись, ну это тоже решаемо, ок.Как на HTML код навесить обработчики из ранее зарегистрированных модулей и не было проблемой, а вот как зарегистрировать новый модуль (и "разрегистрировать" его потом) - вот это не понятно. Пример (несколько извращённый, но вопрос не в примере а в принципиальной возможности загрузить модуль и потом возможно выгрузить): есть страница с кучей разных блоков, у текстовых есть дополнительный класс и настройки для редактирования; при нажатии кнопки подгружается модуль который делает все блоки редактируемыми (вот прямо сразу textarea, а не после click) с какими-то ограничениями по длине строки и всё такое из параметров в блоке; по нажатию кнопки измененные блоки отсылаются на сервер, textarea меняется обратно на текст, регистрация модуля на этих блоках отменяется (в дальнейшем при нажатии блоки превращаются обратно в textarea). Вопрос именно в том что бы добавлять новые модули уже после того как страница инициализирована (загрузка их по требованию), а если есть ещё и возможность их выгрузки - то совсем хорошо. Это же полезно для сложных решений в рамках "one page site". Или допустим реализуем приложение с разными формами со сложными элементами управления которыми подгружается (и регистрируется как модули) вместе с формой (с каждой свой набор, местами пересекающиеся, так что отдельный файл для каждого типа элемента вообще супер) и выгружаются когда форма закрывается.
Надеюсь не запутал окончательно, заранее спасибо =)
P.S.: я конечно угадал что > в начале строки формирует цитату (по старой привычке к email, правда 72 символа в строку не соблюдал ;), но может стоило указать где-то возможности оформления поста в виде хелпика?
М? В пункте «Сообщество» есть документация? o_O
Догрузка модулей в рантайме для приведенных примеров сработает:
<script>
, например).Вот подробнее про то, что умеют модули: https://github.com/ymaps/modules/blob/master/README.ru.md, с асинхронностью все отлично.
Посты оформляются в маркдауне, https://guides.github.com/features/mastering-markdown/ Да, ссылку на эту доку не мешало бы прикрутить на экране отправки сообщения, конечно.
Сообщество -> Форум -> Библиотека (вот тут слева пунктик такой =). Другого способа выйти на этот список я если честно не нашел.
По остальным пунктам понял в какую сторону копать, спасибо!
Серега, какие ещё костыли ты должен вставлять и что-то исправлять, что ты за х...ню несёшь здесь? Я применил этот способ, что бы ввести модульное написание js кода, которое приведёт его в порядок и что бы не видеть кучи твоего (раз уж тебе не ведомы нормальные манеры разговора) говнокода, который после написания тобой никто не может тронуть, ведь даже ты потом не понимаешь что там и как этим управлять. И если ты будешь и дальше позволять себе подобные высказывания, то я перестану обходить углы и делать вид, что ты у нас великий прогер, лишь бы потешить твоё эго. "Если тебе не говорят от твоих проблемах, это не значит что их нет".
Платформа -> Библиотеки
Я видимо и правда динозавр, но "Библиотеки" (lib) совсем не тождественно для меня "Документации" (doc). На форуме же пункт про который я написал находится в разделе именно "ДОКУМЕНТАЦИЯ". =)
Форум — часть старого сайта в старом дизайне. Раздел про библиотеки пока ещё не перевели в новый дизайн.
Всё будет тут:
/platform/libs/