Я тебе сразу сказал, что это можно решить и с помощью третьих модулей, это всего лишь пример, который ты попросил привести к одному из моих аргументов.
Я думаю, тут стоит остановиться ) У любых задач есть несколько способов решения, каждый выбирает какой ему ближе.
Я написал, что эту проблему можно решить с помощью третьих модулей, но часто это бывает просто избыточно.
Пример чего именно ты хочешь чтобы я привел? Вроде я привел их в верхнем комментарии.
Теперь по второму пункту, возможности додекларации/передекларации модуля, примеры:
Код, который работает и в браузере, и на сервере (node.js). Есть некая общая часть, предоставляющая единый интерфейс в модуле для всего остального кода. И есть некоторые специфичные части, зависимые от платформы, на которой код исполняется. Например, модуль, который ходит по http: есть файл http.vanilla.js, в котором декларируется общая часть модуля http, есть файл http.browser.js, в котором додекларируется модуль http реализацией через XmlHttpRequest, и, есть файл http.node.js, где додекларируется http реализаций походом через нодовский http.request.
Для всего остального кода это просто модуль http, он не знает его подробностей. Эту проблему можно было бы решить и по-другому, например, через третьи модули, но зачем? Так гораздо естественней.
Использование в BEM-предметной области, где есть уровни переопределения и финальный рантайм собирается из их суммы.
Мы используем эту возможность в тестах: тесты у нас собираются динамически, то есть мы просто говорим — хочу запустить все тесты из такой-то папки. Каждый тест представляет из себя додекларацию модуля test. В итоге, в раннере тестов мне достаточно сделать modules.require(['test'], function(test) { test.run() }).
Действуем по аналогии с DOMContentLoaded — см мой пример в ready.js
Все-таки, это больше похоже на «Делаем костыли по аналогии с DOMContentLoaded» ;)
В наших проектах мы примерно так и делали до поры до времени, но, в какой-то момент устали костылять подобные вещи (ymaps это далеко не единственный пример). В какой-то момент переписали все на наши асинхронные модули и избавились от этих странных прослоек, и больше даже никогда не задумываемся о них. Для нас игра стоила свеч.
Притом, что эту зависимость мы можем представить как синхронно (тег скрипт) так и асинхронно и вызов require('ymaps') в обоих случаях отработает одинакого.
ymaps нельзя загрузить синхронно через тэг script. Через тэг ты получишь только заглушку, у которой нужно дождаться еще ready.
В «асинхронности» для модулей нет смысла потому как 95% модулей могут быть получены без видимой блокировки основного потока (они загружаются при старте приложения)
О какой блокировке основного потока идет речь при «асинхронности» модулей?
Ты предлагаешь разделить код по неким, достаточно искусственным, принципам. Опять вводя странные зависимости, обеспечиваемые неким кодом снаружи. То есть, опять вводя знания в свой код, что он неработоспособен, пока кто-то где-то как-то снаружи не обеспечит это. А мне кажется (вернее я даже уверен в этом), это одна из задач именно модульной системы. Тем более, верхний пример, вроде как прекрасно это доказывает.
В мире javascript вообще уже довольно странно делить код на синхронный/асинхронный. Например, те же промисы, позволяют тебе не думать об этом. Почему же для модульной системы эти различия должны играть такую роль?
Ты, все-таки, проигнорировал мой основной вопрос — как мне предоставить мои модули-классы, являющиеся наследниками классов стороннего кода, который не умеет быть синхронным, своему остальному коду?
Пример как мы используем асинхронный provide модулей — мы используем api 2.0 Яндекс.карт для наших приложений. Он не умеет в принципе загружаться синхронно. Но при этом у нас есть куча классов-наследников от апишных классов. Как ты предлагаешь делать такие модули-наследники?
У нас это написано просто, есть модуль ymaps:
Как ты предлагаешь разруливать такую ситуацию с синхронным провайдом модуля? Представленная выше ситуация далеко не единственная. И тут речь не идет ни о каких данных для модуля, речь идет о самом модуле.
Насколько я помню, там в тесте Q была версии 0.8, в ней вроде еще не было этой опции.
Сейчас померял с Q 0.9 — там отключение этой опции дает существенный буст, она становится даже чуть быстрее When (примерно на 10-15%).
Что говнокод пишется с помощью любых средств — это несомненно. Только способствовать этому, не применяя общеизвестные практики (прикрываясь их типа сложностью), уменьшающие вероятность говнокода, это темный путь силы. Да и нет ничего сложного в наследовании, это способен понять любой верстальщик.
Про пункт 1 — насколько я помню Sizzle начинает искать справа налево, а не слева направо. Т.е. он сначала найдет все .of, а потом уже будет смотреть, находятся ли они в #traffic_light.
Вы противоречите сами себе — если бы скорость трансформации была насколько узким местом, то Яндекс вряд ли бы ее использовал для подавляющего большинства своих сервисов.
Я думаю, тут стоит остановиться ) У любых задач есть несколько способов решения, каждый выбирает какой ему ближе.
Простой пример, чтобы суть донести:
http.vanilla.js:
http.browser.js:
http.node.js:
Остальной код (что в браузере, что в ноде), просто использует этот модуль http.
Пример чего именно ты хочешь чтобы я привел? Вроде я привел их в верхнем комментарии.
Для всего остального кода это просто модуль http, он не знает его подробностей. Эту проблему можно было бы решить и по-другому, например, через третьи модули, но зачем? Так гораздо естественней.
Ну, то есть, это тупо удобно.
В наших проектах мы примерно так и делали до поры до времени, но, в какой-то момент устали костылять подобные вещи (ymaps это далеко не единственный пример). В какой-то момент переписали все на наши асинхронные модули и избавились от этих странных прослоек, и больше даже никогда не задумываемся о них. Для нас игра стоила свеч.
ymaps нельзя загрузить синхронно через тэг script. Через тэг ты получишь только заглушку, у которой нужно дождаться еще ready.
О какой блокировке основного потока идет речь при «асинхронности» модулей?
В мире javascript вообще уже довольно странно делить код на синхронный/асинхронный. Например, те же промисы, позволяют тебе не думать об этом. Почему же для модульной системы эти различия должны играть такую роль?
У нас это написано просто, есть модуль ymaps:
Потом, где нам надо наследоваться от классов, предоставляемых api, мы просто это делаем, не думая, как оно там загрузилось:
Как ты предлагаешь разруливать такую ситуацию с синхронным провайдом модуля? Представленная выше ситуация далеко не единственная. И тут речь не идет ни о каких данных для модуля, речь идет о самом модуле.
Сейчас померял с Q 0.9 — там отключение этой опции дает существенный буст, она становится даже чуть быстрее When (примерно на 10-15%).