All streams
Search
Write a publication
Pull to refresh
48
0
Send message
Пользуясь случаем, хочу заодно попиарить своё экспериментальное решение, о котором я уже писал на хабре: это загрузчик, который позволяет загружать одни и те же модули (в том числе на лету) и под вебом, и под Node.js вообще без каких-либо преобразований-сборок-итп. В моём понимании именно это есть изоморфный JavaScript (оттранслировать то можно что угодно куда угодно, так что Browserify это уже читерство, а не изоморфный JS ;-) ). Правда, самый существенный недостаток — это, конечно, свой (изоморфный) формат модулей, в который нужно вручную переделывать требуемые библиотеки. Впрочем, я попытался сделать его насколько возможно простым.
Я недавно накатал текст по этому вопросу: gist.github.com/asvd/7619633

Всё никак руки не доходят перевести.

Если совсем грубо говоря, то примерно вот почему: в подходах, где есть экспортирование объекта из модуля, мы искуственно связываем внутреннюю структуру библиотеки (то, как она разбита на модули) и её АПИ (экспортируемый объект). Поэтому если например позже захочется переделать структуру проекта, нужно будет приложить немало усилий, чтоб сохранить интерфейс.
Интересно, я об этом ещё не задумывался, надо поразбираться.

Проблема в том, что если снаружи всех функций написать var init = ..., то, насколько я помню, для nodejs будет объявлена всё равно локальная переменная модуля, и возможно это сломает совместимость…
Спасибо, интересная библиотека, может быть по способу записи ближе всего к Helios Kernel. Только странно, что у steal столько разнообразного функционала: у меня впечатление, что некоторые вещи должны быть в виде отдельных серверных инструментов (steal.clean).

Про формат записи это же вопрос вкуса. Мне кажется, тут нужно стремиться не к компактности и минимальному размеру кода, а к ясности. Конкретно в steal такое место — аргументы функции steal, которые могут менять свой смысл (быть путём или колбэком) в зависимости от их количества. Ну то есть я бы не стал определять например тело модуля в виде анонимной функции прямо в перечислении аргумента только лишь потому, что язык позволяет этим способом сделать запись более компактной.

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

А функция init() в некотором смысле даже аналогична сишному int main(). Её логичнее было именно определять в теле модуля, а не передавать в качестве аргумента как раз потому что это не колбэк.
Так этот пост собственно и есть почти целиком про профиты. Вы правы в том, что мне было скорее интересно сделать эту штуку, но если бы не было профита — я бы наверное и не начинал.

Ну или можно объявить киллерфичей возможность запуска приложения в nodejs и в web без изменений и трансляции. У меня есть мысли развить проект как раз в эту сторону.
Если бы создатели этих вариантов следовали тогдашним «стандартам де-факто», не было бы сейчас ни нода, ни commonjs. Был бы бэкэнд на php и инклюд через script
Возможно, но не в этом суть.

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

Ну и в итоге получается два способа делать одно и то же.
Почему PHP? Тогда уж Си например :-)
Пути же относительные. В крайнем случае, аргумент для include() можно генерить (если вы хотите в вашем проекте часто менять расположение модулей, но мне кажется не стоит это часто делать). Или какая гибкость имеется в виду?
Код не может выполняться по кругу, разрешать циклические зависимости может иметь смысл только для случая, когда два модуля используют объекты друг друга «крест-накрест». Это пример плохого дизайна, поэтому запрет циклических зависимостей помогает этого избежать. Есть циклическая зависимость — нужно выделить общий код в отдельный модуль, потом проще же поддерживать будет. Так что это является даже преимуществом, а не недостатком.

Других ограничений Helios Kernel не накладывает (в сравнении с require из nodejs) — код модуля расположен в функции init(), там можно делать что угодно. Это менее ограничивающий подход в сравнении с exports, где всегда нужно создавать и экспортировать объект.

Функциональность выгрузки задумывалась для веба. Загрузились какие-то данные, мы с ними поработали, они больше не нужны — мы их выгрузили.

У Helios Kernel нет двух версий для веба и для nodejs, это один и тот же код, который работает одинаково под обоими средами.

А вообще, идея с работой в nodejs появилась ради возможности создавать совместимые модули, которые без конвертации будут работать и в node и в вебе.
include() уже так и работает
Вроде бы в AMD «module ID» мэпится в путь по конфигам и обстоятельствам? Это как раз хороший пример лишней функциональности, без которой я хотел обойтись. Это может быть удобно использовано, если нужны разные версии одной библиотеки. Но из-за этой возможности нельзянаверняка сказать, где именно расположен исходник модуля.

Мне кажется, вы ожидаете от Helios Kernel, что он должен обладать возможностями AMD, но на мой взгляд Helios Kernel даже и не совсем конкурент, он претендует быть решением скорее не для модулей, которые генерят объекты на экспорт, а для файлов с исходным кодом. Внутри функции init() может быть что угодно, любой код, который будет выполнен как только модуль загрузится. То есть, хотелось сделать что-то вроде аналога макроса инклюд.

Продолжая думать в эту сторону — код внутри функции init(), в том числе и определять объекты модулей в формате наподобие AMD, с экспортом зависимостей и без коллизий. Это можно было бы реализовать поверх в виде отдельной библиотеки с умным разруливанием зависимостей и генерацией имени файла по id модуля, такая библиотека могла бы использовать kernel.require() для загрузки нужных модулей (интересная кстати мысль)

Но моя идея состоит в том, что без этих фич часто можно обойтись. Особенно если формат модуля при этом проще становится. Поэтому про Helios Kernel можно сказать, что это решение
для управления зависимостей между js-скриптами без лишних наворотов.
AMD-подход создаёт сложности при конфигурации и описании модулей и делает зависимости неочевидными. Я здесь пытаюсь как раз таких сложностей избежать.

А что для вас сложностью является? Определение библиотечного объекта или соглашение об именовании?
Вы можете также описать какую-нибудь функцию для автоматического построения пустого объекта. Тогда достаточно будет написать что-то вроде

// "Экспортируемый" объект
createNamespace("collection.filtered");

// Разные штуки, предоставляемые вашей билиотекой - модулем
collection.filtered.paginated = SomeFabricCall({});

collection.filtered.whatever = ...


Иными словами — да, предлагается (но не обязательно) определять в каждом модуле один глобальный объект в котором будет всё остальное.
На сайте описано на английском, сейчас не успею ответить. Возможно, вечером отпишусь
Да, переменную определяет автор модуля в его функции init(). На сайте описано, как это делается
Библиотека с разруливанием таких случаев никак не взаимосвязана. Здесь-то как раз случай простой- когда такие объекты создаются в пределах одного проекта, достаточно просто договориться об именовании, например как я привёл выше.

Более «сложный» случай — это когда что-то инклюдится, и коллизии возникают где-то глубоко в зависимостях, а мы даже не знаем, где конкретно.

А вообще у меня основной тезис как раз состоит в том, что если вынести этот вопрос за пределы компетенции библиотеки, то это позволит сильно упростить управление зависимостями. Политику именования объектов при этом можно выбирать как угодно, не привязываясь к ограничениям библиотеки.
models.Abstract и views.Abstract например?
В Мюнхене в ведомстве по делам иностранцев заполнял бланк как раз таким образом на прошлой неделе. Девушка выдала два бланка с копиркой между ними, соединёнными скрепками.

После заполнения она проверяет, что всё хорошо «откопировалось», и либо обводит ручкой непонятные места, либо несёт ксерить оригинал бланка.
ну мне кажется, что мой способ проще и яснее. поэтому я и пытаюсь сделать что-то альтернативное и посмотреть, как это будет работать.

ну а иначе всем скучно было бы — ещё один велосипед для AMD :-)

Information

Rating
Does not participate
Location
Санкт-Петербург, Санкт-Петербург и область, Россия
Registered
Activity