Closed lilliputten closed 8 years ago
modules.define
ничего не знает и никак не связан с jquery.ready
.
Можно собрать минимальный пример, иллюстрирующий проблему?
@dfilatov, да, define
только сохраняет переданные ему данные в modulesStorage
, а вот инициализируется всё уже, наск. понял, по пинку от jQuery.complete
.
Попробовал собрать пример, насколько возможно, более близко повторяющий реальную ситуацию:
Архив ~55К: test.zip
Если раскомментировать строчку <script id="test1-browser-script" src="test.browser.js"></script>
, то "динамический" скрипт не будет загружаться. Этот же будет загружен и кто-то (видимо, всё же i-bem?) выполнит инициализацию блока: т.е., второй фрагмент безо всяких предварительных вызовов require
(оно тоже не будет выполняться, т.к. динамическая загрузка не производилась) покажет блок, который будет проинициализирован.
Код в test1.js
пытается создать что-то похожее на то, что происходит в
приложении:
Перед тем, как создавать блок, смотрим в конфиг, где нам говорят, что надо загрузить пакеты с шаблонами и клиентским кодом. Грузим, по коллбеку вызваем код, создающий блок.
В жизни всё немножко не так, но в целом вроде картина правильная. Самое главное, что эти куски находятся совсем в разных местах и не очень знают друг о друге -- специально не стал завязывать второй фрагмент на завершение загрузки для наглядности (таймаут гарантирует выполнение после загрузки).
Т.е., если не делать modules.require(['test1'], ...
после загрузки модуля, то
ничего не сработает. Сейчас это кажется уже более логичным.
Видимо, придётся делать в пакете с модулями (их там, по идее много -- всё, что
нужно для отрисовываемого элемента интерфейса) "оглавление" и так или иначе по
завершении загрузки вызывать для них require
.
Наверное, это естественное поведение и вариантов нету?
@dfilatov Дим, а что в итоге с Promise.resolve? Хотелось бы, чтобы YM сама это делала.
@zxqfox про Promise.resolve это вообще про что? В ym нет никаких промисов.
@lilliputten я правильно понимаю что от test1 никакой другой модуль в подгружаемом бандле не зависит?
@dfilatov Про export default new Promise();
и чтоб на том конце в import
не надо было всё это заворачивать в import x from 'x'; Promise.resolve(x).then((x) => { ... });
@zxqfox Я чего-то совсем перестал понимать, как модули из es2015 связаны с этим issue?
@dfilatov Так. Еще раз с начала. Человек пришел с проблемой: у него модуль грузит другие модули асинхронно. Реализация, которую ему предложил @tadatuta, на промисах. Я вспомнил, что были мысли поддержать это на уровне ym.
modules.define('x', function(provide) {
provide(Promise.resolve(42));
});
modules.require(['x'], function(x) {
console.log(x); // 42
});
И решил спросить).
Модули из es2015 можно без проблем перегонять в любой модульный формат, и мне так показалось короче. Зря показалось).
@zxqfox Непонятно, зачем это делать (поддерживать промисы в модульной системе).
Вместо:
provide(Promise.resolve(42));
Напиши:
Promise.resolve(42).then(provide);
и никакой специальной поддержки от модульной системы не нужно.
@dfilatov потому что это логично возвращать значение, модульная система этим и занимается.
@zxqfox Не вижу ничего логичного в том, чтобы вводить поддержку дополнительной сущности, когда и без нее можно обойтись, причем с точностью до синтаксиса. Мне как раз импонирует математический подход, когда ты сводишь решение новой задачи к решению предыдущей, а не придумываешь каждый раз новый способ.
@dfilatov Ну подожди, тогда почему не вернуться на шаг назад и не сделать более совместимую с AMD модульную систему. Ведь можно делать return new Promise()
и не надо будет прокидывать provide аргументом в тело. Это, конечно, не решит вопросов доопределения через аргумент.
Впрочем, это совсем оффтоп. Давай в другой раз.
@zxqfox Ну так оно же не сводится )
@dfilatov
я правильно понимаю что от test1 никакой другой модуль в подгружаемом бандле не зависит?
В общем случае неизвестно и скорее всего там будут и внутренние зависимости. Это может как-то повлиять?
Если я правильно понял, для моей ситуации решением получается реквайринг 'i-bem__dom_init'
после загрузки пакета и определения модулей в нём?
Сейчас буду пробовать экспериментировать уже в рабочем проекте. Хотя в целом вроде бы это уже к самому YM отношения не имеет, -- т.е., слегка оффтоп получился.
Использую ym в составе bem/enb/i-bem для клиентского кода блоков. При попытке загружать файлы модулей динамически (через js
document.createElement('script')...
вместо статического<script src="..."></script>
) происходит сбой и до вызоваdecl.fn.apply
дело не доходит.Насколько сейчас понимаю, дело в том, что
modules.define
определяется после отработкиjQuery.ready
(где происходит всё это шаманство сnextTick
,requireDeps
,startDeclResolving
и пр.Сейчас удалось добиться запуска модуля вызовом
modules.require(...)
после загрузки файла с кодом.Насколько это нормально? Как лучше решать вопрос?
Описание проблемы на форуме bem.info