Комментарии 97
В принципе, этот пост покрывает 90% того, что нужно знать про RequireJS. Спасибо!
Очень полезная штука в случае многофункционального приложения на JS. Жаль только, что большая часть библиотек полагаются на глобальную область видимости — приходится делать обертки, или переписывать, чтобы общая логика работы с файлами при разработке не менялась.
Кроме плюсов, у использования AMD есть и минусы. В основном они связаны с тем, что это не настолько распространенная технология, как хотелось бы. Например, написание unit-тестов с помощью известных тестовых фремворков и их исполнение при работе с AMD требует требует допиливания запускаторов (использую JSTestDriver, для которого написан адаптер, но все равно периодически глючит).
Ещё не стоит забывать, что технологии AMD построены поверх JavaScript, и чудес тут не будет.
Кроме плюсов, у использования AMD есть и минусы. В основном они связаны с тем, что это не настолько распространенная технология, как хотелось бы. Например, написание unit-тестов с помощью известных тестовых фремворков и их исполнение при работе с AMD требует требует допиливания запускаторов (использую JSTestDriver, для которого написан адаптер, но все равно периодически глючит).
Ещё не стоит забывать, что технологии AMD построены поверх JavaScript, и чудес тут не будет.
Технология AMD очень молодая, ей всего около года (описание API на GitHub и первые релизы RequireJS). Надеюсь, со временем её подхватят контрибьюторы плагинов и библиотек, как это было с jQuery. А Underscore.js в релизе 1.3.0, напротив, отказались от AMD.
Вместо Underscore могу порекомендовать lodash.
github.com/amdjs/underscore github.com/amdjs/backbone AMD Underscore 1.3.3 и Backbone.js 9.2 соотвественно
поддерживаю, заявлено много багфиксов и ускорение. ускорение по тестам вроде есть, в реальной жизни пока не понял — все и так летает.
В YUI уже года четыре применяется
Технология? Решение в 200 строчек кода теперь называется технологией? Вы серьезно?
Согласен, громковато сказано. «Техника» было бы уместнее.
Технология (от др.-греч. τέχνη — искусство, мастерство, умение; λόγος — мысль, причина; методика, способ производства) — в широком смысле — совокупность методов, процессов и материалов, используемых в какой-либо отрасли деятельности, а также научное описание способов технического производства; в узком — комплекс организационных мер, операций и приемов, направленных на изготовление, обслуживание, ремонт и/или эксплуатацию изделия с номинальным качеством и оптимальными затратами, и обусловленных текущим уровнем развития науки, техники и общества в целом.
(http://ru.wikipedia.org/)
AMD — технология поддержки модульности кода. Технически она реализована с помощью функций, замыканий и пр. конструкций, предлагаемых языком. С т.з. пользователя, это обычная модульная технология, и он ждет от неё таких же возможностей, как и от пакетов в Java или C# и т.д., но у технической реализации есть ограничения.
Пассаж про количество строк я не понял. ;)
Уже два года назад RequireJS можно было нормально пользоваться.
Если не верите, можете, например, историю коммитов посмотреть.
Если не верите, можете, например, историю коммитов посмотреть.
Underscore.js прекрасно подхватывается с помощью shim в конфиге, как описано в посте.
В случае jQuery на самом сайте RequireJS предлагают использовать гибрид ужа и ежа require-jquery.js. Что позволяет без проблем использовать плагины без поддержки AMD (которых 99.99%)
А разве jQuery из коробки не поддерживает AMD?!
НЛО прилетело и опубликовало эту надпись здесь
Недавно копался в require.js, возможно, кому-то сэкономят время ссылки на AMD underscore 1.3.3 и backbonejs 9.2 github.com/amdjs/underscore github.com/amdjs/backbone
Вас не напрягает постоянно писать подобную обертку и менять пути во всех файлах в случае изменения его места или его зависимостей?
Не кажется ли, что nodejs-way модули и зависимости, которые лежат вне модуля более естественны? Плюс приходит консистентность модулей на клиенте и сервере.
PS Спрашиваю не ради холивара.
define(["exports", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-prop"],
function (exports, has, lang, dom, style, prop) {
// code
});
Не кажется ли, что nodejs-way модули и зависимости, которые лежат вне модуля более естественны? Плюс приходит консистентность модулей на клиенте и сервере.
var exports = require("exports"),
has = require("./sniff"),
lang = require("./_base/lang"),
dom = require("./dom"),
style = require("./dom-style"),
prop = require("./dom-prop");
PS Спрашиваю не ради холивара.
НЛО прилетело и опубликовало эту надпись здесь
На данный момент я разрабатываю альтернативу AMD/RequireJS — LMD. В нем писать такие модули можно из коробки. В данном топике я пытаюсь получить фидбэк от активных пользователей RequireJS и сделать LMD еще лучше.
А вы browserify видели?
Если вкратце, в чем преимущества вашего подхода перед browserify?
Если вкратце, в чем преимущества вашего подхода перед browserify?
Да, конечно. В первую очередь я не позиционирую LMD как адаптр Node.js модулей(не пытаюсь перенести окружение Node.js среды в Dom.js). LMD — сборщик, оптимайзер, загрузчик, профайлер. Он ближе к RequireJS.
Концептуальное различие в том, что browserify использует «детектива» для статического поиска зависимостей — следовательно browserify не умеет из коробки подгружать модули динамически, не может делать так
Кроме концептуальных особенностей они различаются набором фичей (на которые просто нужно время) — browserify может работать с .coffee, LMD — нет. Есть и несколько других штук, которые LMD не умеет (SourceMap) и возможно не будет уметь(jade-компилятор).
LMD, в свою очередь, имеет встроенный прозрачный кэшер в localStorage, ленивую инициализацию модулей, встроенный code coverage tool (для динамических файлов без участия сервера) и профайлер модулей. Все это предельно просто включается.
Концептуальное различие в том, что browserify использует «детектива» для статического поиска зависимостей — следовательно browserify не умеет из коробки подгружать модули динамически, не может делать так
require('pewpew-ololo' + someVar);
. Соответственно LMD умеет рабоать с модулями динамически, но приходится писать конфиг, который делает жизнь ни чуть не сложнее.Кроме концептуальных особенностей они различаются набором фичей (на которые просто нужно время) — browserify может работать с .coffee, LMD — нет. Есть и несколько других штук, которые LMD не умеет (SourceMap) и возможно не будет уметь(jade-компилятор).
LMD, в свою очередь, имеет встроенный прозрачный кэшер в localStorage, ленивую инициализацию модулей, встроенный code coverage tool (для динамических файлов без участия сервера) и профайлер модулей. Все это предельно просто включается.
Не обязательно писать полные пути до файлов. Можно в конфиге RequireJS указать пути:
requirejs.config({
<...>
paths: {
jquery: 'third-party/jquery.min',
underscore: 'third-party/underscore.min',
backbone: 'third-party/backbone.min',
<...>
},
});
И если даже что-то изменится, то достаточно будет поменять путь к файлу в загрузчике.Спасибо. Как правило у среднего проекта бывает штук 20 файлов и тогда придется прописывать все аллиасы в одном месте. Те рано или поздно настанет такой момент, когда этот список станет неподдерживаемым. Есть ли возможность сделать наследование конфигов?
gist.github.com/3806235
у нас paths вот такой и ничего. удобно
у нас paths вот такой и ничего. удобно
Удобно понятие в данном случае относительное :) А как вы делаете production/development/testing сборки, когда необходимо заменить один из элементов такого списка?
про тесты сказать не могу ничего. пока не могу.
про продакшн — в билде на node.js + r.js я указываю какие файлы не билдить, какие подменить
про продакшн — в билде на node.js + r.js я указываю какие файлы не билдить, какие подменить
а вообще у нас пока этой проблемы нет. файлы которые на деве — те же и на проде.
меняется только конфигурационный файл, который мы выключили из билда и на каждом сервере он свой
меняется только конфигурационный файл, который мы выключили из билда и на каждом сервере он свой
Я вот так делал в paths:
Теперь, при запросе модуля
'dataAccess': devMode ? 'dataAccessMock' : 'dataAccessWs'
Теперь, при запросе модуля
'dataAccess/userData'
, будет подгружен модуль из папки, соответствующей текущему контексту.В приложении, над которым я работаю, порядка 600-700 отдельных JS файлов. Но для продакшена они склеиваются в один, режутся комментарии, сжимаются. Для отладки склеиваются в пару десятков, помодульно. Над проектом в данный момент с клиентской стороны работают 7 человек. И никаких проблем с путями. Обычно они прописываются один раз и навсегда.
Вот не вижу как наследование конфигов может решить сложность зависимостей. Скорее только усугубит — надо будет бегать по конфигам, чтобы найти откуда растут ноги и в каком месте возникает конфликт.
Вот не вижу как наследование конфигов может решить сложность зависимостей. Скорее только усугубит — надо будет бегать по конфигам, чтобы найти откуда растут ноги и в каком месте возникает конфликт.
Можно используя development сборку красиво унаследовать от нее production (переписать конфиг, добавить плагинов, включить сжатие). Так же я не представляю как можно писать адекватные конфиги для локализированных сборок (копипаст либо препроцессоры), а наследование может гибко изменить особенность каждый сборки (не только локаль).
Пути менять не придётся, если описать в
require.config( { paths: [] } );
алиасы к библиотекам. А по поводу обёртки да, такой формат будет удобнее, если миллион зависимостей. Вот в документации пишут про него.А не надо писать в обсолютных путях. Вы прописываете в настройке baseUrl и потом в зависимостях спокойно пляшете от него, без вводного слэша:
Это спасает, если вдруг вы переместили всю папку со скриптами, а структура не поменялась. Если же внезапно меняется структура проекта, то это довольно странно. Как если бы в Java класс внезапно сменил пакет, его тоже пришлось бы вручную переподключать везде, где он импротится.
define([
"exports",
"sniff",
"_base/lang"
],
function(exports,has,lang){
...
})
Это спасает, если вдруг вы переместили всю папку со скриптами, а структура не поменялась. Если же внезапно меняется структура проекта, то это довольно странно. Как если бы в Java класс внезапно сменил пакет, его тоже пришлось бы вручную переподключать везде, где он импротится.
Предположим вам необходимо, чтобы какой-то модуль лениво инициализировался (он должен быть загружен, быть в сборке, но не выполнен). Используя схему define() он будет инициализирован в начале — не подходит. А если не включить его в define() и вызывать через require(), то он по умолчанию не попадет в сборку(возможно я ошибаюсь). Как решается эта проблема?
define может возвращать не уже готовый модуль, а функцию его инициализирующую, например:
define(function(){
return function(){
var A = function(){}
A.prototype = { ... }
return A;
}
})
я решаю следующим образом: мой сайт разбит на «модули». есть common, для него одна сборка, со всеми библиотеками и их расширениями, и есть конкретные, грубо говоря page1.js, page2.js, являющиеся страницами сайта.
в начале грузится common, потом в зависимости от урла — нужный модуль. маленький и красивый, ничего лишнего.
в начале грузится common, потом в зависимости от урла — нужный модуль. маленький и красивый, ничего лишнего.
requirejs.org/docs/commonjs.html 4 параграф
В requirejs можно писать в стиле Ноды.
В requirejs можно писать в стиле Ноды.
Да отчасти, но чтобы использовать такое в node.js (ну вдруг надо будет), то придется подключить какой-нибудь require-node.
Те мы фактически навешиваем еще один слой абстракции над уже существующей системой модулей. А хочется все-таки не писать обертку.
define(function (require) {
});
Те мы фактически навешиваем еще один слой абстракции над уже существующей системой модулей. А хочется все-таки не писать обертку.
Ну requirejs все-таки, имхо, клиентский фреймворк. На ноде не пишу, так что не не знаю какие там реалии.
CommonJS Modules 1.1 != 2.0
RequireJS Использует 2 версию модулей и то коряво
RequireJS Использует 2 версию модулей и то коряво
Вот совпадение. Делаю как раз сейчас перевод этой статьи. Как считаете, стоит продолжать?
А можно забандлить все модули в один .js файл, что бы не делать десяток http-запросов?
Можно, в RequireJS есть утилита для сборки и оптимизации, которая это делает.
Да, вот как раз про это раздел в документации.
Можно собрать все файлы при помощи r.js
Вообще идеология — один файл=один модуль. Иначе теряется смысл асинхронной загрузки модулей. Но я делаю так: если какие-то модули нужны исключительно в одном большом модуле, то я пишу несколько define в одном файле и возвращаю только основной модуль, так что он подключает все свои зависимости, объявленные в этом же файле, а другие не могут. Для этого надо явно указывать в define имя модуля и вызывать зависимость не по пути, а по имени. Например модуль B.js:
Теоретически, после загрузки B все смогут подключать А по имени, но никто не знает, когда В загрузится, а до А напрямую достучаться нельзя.
Вообще идеология — один файл=один модуль. Иначе теряется смысл асинхронной загрузки модулей. Но я делаю так: если какие-то модули нужны исключительно в одном большом модуле, то я пишу несколько define в одном файле и возвращаю только основной модуль, так что он подключает все свои зависимости, объявленные в этом же файле, а другие не могут. Для этого надо явно указывать в define имя модуля и вызывать зависимость не по пути, а по имени. Например модуль B.js:
define("A", function(){ ... });
define ("B", ["A"], function("B"){ ... });
Теоретически, после загрузки B все смогут подключать А по имени, но никто не знает, когда В загрузится, а до А напрямую достучаться нельзя.
Решает ли r.js проблему циклической зависимости?
define("A", ["B"], function(B){ ... });
define("B", ["A"], function(A){ ... });
нет, так работать не будет
Боюсь, что r.js такое правильно не соберет, но в принципе в requirejs предусмотрены циклические зависимости: requirejs.org/docs/api.html#circular
Хотя, если один кусок кода не работает без другого, а второй без первого, то они должны быть одним модулем, имхо.
Хотя, если один кусок кода не работает без другого, а второй без первого, то они должны быть одним модулем, имхо.
Такое и в ноде не будет абсолютно корректно работать. В один из модулей второй подгрузится не до конца инициализировнным.
Интересно, месяц назад написал адаптацию классического паттерна призванного решать эти же проблемы. Но получил минусы в карму с аргументацией — «В Javascript это не нужно!».
Не соглашусь. В Service Locator классы сами определяют свои зависимости, пусть даже и при помощи Service Locator. В моей реализации классы получают все зависимости извне, и они не знают, как и кем, они определяются и передаются. Безусловно, я написал там, что это не Auto DI как таковой, но по идеологии он намного ближе к нему, а не к Service Locator.
А никто еще не написал server-side решение для компиляции модулей ES Harmony в один файл с заменой неподдерживаемых сейчас инструкций?
code.google.com/p/traceur-compiler/ + какой-нибудь сборщик и будет
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
по остальным пунктам все понятно, но второй…
По-умолчанию, requirejs шлет AJAX-реквесты, когда вызывается require и модуль не находится в кеше. Такой подход просто невероятно неэффективен в продакшене. Ведь круче сжать все в один файл и работать с синхронными модулями. Асинхронная дозагрузка может быть полезна только на штуках типа локализаций, но их можно прибить и к common.js тоже.
а как же optimize? все так как ты пишешь
По-умолчанию, requirejs шлет AJAX-реквесты, когда вызывается require и модуль не находится в кеше. Такой подход просто невероятно неэффективен в продакшене. Ведь круче сжать все в один файл и работать с синхронными модулями. Асинхронная дозагрузка может быть полезна только на штуках типа локализаций, но их можно прибить и к common.js тоже.
а как же optimize? все так как ты пишешь
НЛО прилетело и опубликовало эту надпись здесь
Можно и так, но зачем? Не лучше ли иметь окружение разработки (асинхронные модули) консистентное с окружением продакшена (конкатенированные синхронные модули)?
я не понял, а в чем разница моего и твоего подхода?
Однако дебажить конкат. файлы в целом довольно просто, буквально за сутки можно привыкнуть.
пока не привык дебажить один сбилженный на продакшене.
И этот аргумент умрет с повсеместным распространением source maps (конец этого года).
ждем-посмотрим:)
я не понял, а в чем разница моего и твоего подхода?
Однако дебажить конкат. файлы в целом довольно просто, буквально за сутки можно привыкнуть.
пока не привык дебажить один сбилженный на продакшене.
И этот аргумент умрет с повсеместным распространением source maps (конец этого года).
ждем-посмотрим:)
я тут написал обзор методов модуляризации. думаю он будет небезынтересен тут присутствующим.
nin-jin.github.com/etc/modules/index.xml
пишите тут в коментах плюсы и минусы упомянутых подходов. об ошибках и неточностях тоже. есть ли подходы, которые я не упомянул, а стоило бы?
nin-jin.github.com/etc/modules/index.xml
пишите тут в коментах плюсы и минусы упомянутых подходов. об ошибках и неточностях тоже. есть ли подходы, которые я не упомянул, а стоило бы?
JAM — Что не нравится: статический анализ сильно ограничивает, возможен overhead по коду, по соглашениям получается какая-то Java, модули ничем не ограничены, нет ленивой инициализации(все сразу интерпретируется).
В
В
require()
на самом деле больше плюсов, чем минусов: он явный(документация зависимостей по коду, IDE не ругается на глобалы), с помощью него возможна ленивая инициализация модуля. Это полезный слой абстракции, который может изменить способ загрузки модуля (.coffee -> .js), а так же позволяет собирать статистику без наглых хаков.> статический анализ сильно ограничивает
а что именно? для динамической загрузки (необходимость которой сильно преувеличена) можно использовать хоть тот же requireJS. статический анализ на самом деле даёт гораздо больше возможностей. можно даже статически превращать модули хоть в LMD, хоть в AMD, хоть в CJS
> возможен overhead по коду
имеется ввиду, что рядом с каждым модулем нужно писать имя пакета? он не большой и, кстати, легко минимизируется статически. у меня даже был минификатор, который находил пары пакет-модуль и заменял их на короткие алиасы во всех файлах (скрипты, стили, шаблоны и даже серверные скрипты), выхлоп от этого был мизерный, а отлаживать минифицированный код — то ещё удовольствие. Ещё у меня была версия с заворачиванием кода в with( $jam ) with( $wc ) { $Component(… ) } то есть, модули используются без указания пакета, но пакеты в которых нужно искать модули перечисляются вначале файла, но из-за этого возникала неоднозначность вида «а это модуль из какого пакета?», что вносило лишь путаницу и проблемы при переносе кода между файлами (а подключён ли нужный пакет? а не используется ли модуль из не того пакета?). В результате я остановился на варианте: вырезаем коментарии и отступы, склеиваем и зипуем. А одинаковые последовательности — очень хорошо зипуются)
> по соглашениям получается какая-то Java
это каким местом? в яве используются развесистые пространства имён, что напрягает. тут же больше похоже на php с его автолоадом.
> модули ничем не ограничены
а чем они должны быть ограничены? там вся и соль, что PMS и JAM в частности не мешают реализовывать приложение так как хочется. Они лишь помогают работать с зависимостями.
> нет ленивой инициализации(все сразу интерпретируется).
ну, время интерпретации — это такой мизер, что его даже измерить толком не получается. вот тут я стенал по этому поводу: nin-jin.ya.ru/replies.xml?item_no=76
так что временем интерпретации можно пренебречь. а вот что модуль будет делать при старте, а что по необходимости — это уже зависит от разработчика этого модуля)
> В require() на самом деле больше плюсов, чем минусов: он явный(документация зависимостей по коду,
если в этом есть необходимость, в PMS несложно сделать вывод списка зависимостей для каждого модуля, также как сейчас это делается для пакетов. так что посмотреть от чего зависит не сложно. а вот захламлять код портянкой require() и заставлять за ними следить вручную — плохо. в результате получается объявление зависимостей в двух местах («по факту использования» и «по факту включения»), которые обязаны быть синхронизированными.
> IDE не ругается на глобалы),
тут стоило бы уточнить что за ide. komodo вот, например, не ругается. видимо потому, что в глобальной области видимости слишком много всего-всего и с каждым релизом браузеров становится всё больше и больше. вести реестр этих свойств — неблагодарное занятие. а та ide, что следит за глобальными перемеными, могла бы для приличия хотябы просканировать файлы проекта на предмет определения глобальных переменных.
> с помощью него возможна ленивая инициализация модуля.
а если нужно не весь модуль инициализировать лениво, а только часть? опять же, нет смысла смешивать зависимости и ленивые вычисления. это перпендикулярные понятия, которые лучше оставить независимыми.
> Это полезный слой абстракции, который может изменить способ загрузки модуля (.coffee -> .js),
MPS как бы из коробки поддерживает различные форматы. научить его ещё и варить кофе — не проблема. другое дело, что этот синтаксический сахар не стоит тех проблем с отладкой, которые он вызывает.
> а так же позволяет собирать статистику без наглых хаков.
о какой статистике идёт речь?
а что именно? для динамической загрузки (необходимость которой сильно преувеличена) можно использовать хоть тот же requireJS. статический анализ на самом деле даёт гораздо больше возможностей. можно даже статически превращать модули хоть в LMD, хоть в AMD, хоть в CJS
> возможен overhead по коду
имеется ввиду, что рядом с каждым модулем нужно писать имя пакета? он не большой и, кстати, легко минимизируется статически. у меня даже был минификатор, который находил пары пакет-модуль и заменял их на короткие алиасы во всех файлах (скрипты, стили, шаблоны и даже серверные скрипты), выхлоп от этого был мизерный, а отлаживать минифицированный код — то ещё удовольствие. Ещё у меня была версия с заворачиванием кода в with( $jam ) with( $wc ) { $Component(… ) } то есть, модули используются без указания пакета, но пакеты в которых нужно искать модули перечисляются вначале файла, но из-за этого возникала неоднозначность вида «а это модуль из какого пакета?», что вносило лишь путаницу и проблемы при переносе кода между файлами (а подключён ли нужный пакет? а не используется ли модуль из не того пакета?). В результате я остановился на варианте: вырезаем коментарии и отступы, склеиваем и зипуем. А одинаковые последовательности — очень хорошо зипуются)
> по соглашениям получается какая-то Java
это каким местом? в яве используются развесистые пространства имён, что напрягает. тут же больше похоже на php с его автолоадом.
> модули ничем не ограничены
а чем они должны быть ограничены? там вся и соль, что PMS и JAM в частности не мешают реализовывать приложение так как хочется. Они лишь помогают работать с зависимостями.
> нет ленивой инициализации(все сразу интерпретируется).
ну, время интерпретации — это такой мизер, что его даже измерить толком не получается. вот тут я стенал по этому поводу: nin-jin.ya.ru/replies.xml?item_no=76
так что временем интерпретации можно пренебречь. а вот что модуль будет делать при старте, а что по необходимости — это уже зависит от разработчика этого модуля)
> В require() на самом деле больше плюсов, чем минусов: он явный(документация зависимостей по коду,
если в этом есть необходимость, в PMS несложно сделать вывод списка зависимостей для каждого модуля, также как сейчас это делается для пакетов. так что посмотреть от чего зависит не сложно. а вот захламлять код портянкой require() и заставлять за ними следить вручную — плохо. в результате получается объявление зависимостей в двух местах («по факту использования» и «по факту включения»), которые обязаны быть синхронизированными.
> IDE не ругается на глобалы),
тут стоило бы уточнить что за ide. komodo вот, например, не ругается. видимо потому, что в глобальной области видимости слишком много всего-всего и с каждым релизом браузеров становится всё больше и больше. вести реестр этих свойств — неблагодарное занятие. а та ide, что следит за глобальными перемеными, могла бы для приличия хотябы просканировать файлы проекта на предмет определения глобальных переменных.
> с помощью него возможна ленивая инициализация модуля.
а если нужно не весь модуль инициализировать лениво, а только часть? опять же, нет смысла смешивать зависимости и ленивые вычисления. это перпендикулярные понятия, которые лучше оставить независимыми.
> Это полезный слой абстракции, который может изменить способ загрузки модуля (.coffee -> .js),
MPS как бы из коробки поддерживает различные форматы. научить его ещё и варить кофе — не проблема. другое дело, что этот синтаксический сахар не стоит тех проблем с отладкой, которые он вызывает.
> а так же позволяет собирать статистику без наглых хаков.
о какой статистике идёт речь?
>а что именно?
> а чем они должны быть ограничены
тем, что они не должны, по крайней мере, лежать в одном скоупе
> нет ленивой инициализации
кроме времени инициализации, которое нужно замерять в доисторических системах и мобильниках, существуют еще и ресурсы, события, вычисления, которые тянет каждый модуль.
> заставлять за ними следить вручную
Лучше явно чем как-то так автоматически. require() дает возможноть использовать любые имена импорта втч короткие. Максимум документации должно быть в коде — код должен быть самодокументируемым. То, что доки где-то лежат вне файла многим наплевать(не удобно туда-сюда прыгать).
> а только часть
делим модуль на 2 части во время оптимизации
> нет смысла смешивать зависимости и ленивые вычисления
в require() ленивая загрузка — бонус архитектуры
> не стоит тех проблем с отладкой, которые он вызывает
Согласен, просто как вариант. С require() возможно автоматическое применение Code Coverage инструкций без участия бэкэнда.
> а так же позволяет собирать статистику без наглых хаков
Статистика подключений — вызовы require(), профилирование времени инициализации модуля, сбор динамической статистики.
var r = require;
r("pewpew-ololo");
> а чем они должны быть ограничены
тем, что они не должны, по крайней мере, лежать в одном скоупе
> нет ленивой инициализации
кроме времени инициализации, которое нужно замерять в доисторических системах и мобильниках, существуют еще и ресурсы, события, вычисления, которые тянет каждый модуль.
> заставлять за ними следить вручную
Лучше явно чем как-то так автоматически. require() дает возможноть использовать любые имена импорта втч короткие. Максимум документации должно быть в коде — код должен быть самодокументируемым. То, что доки где-то лежат вне файла многим наплевать(не удобно туда-сюда прыгать).
> а только часть
делим модуль на 2 части во время оптимизации
> нет смысла смешивать зависимости и ленивые вычисления
в require() ленивая загрузка — бонус архитектуры
> не стоит тех проблем с отладкой, которые он вызывает
Согласен, просто как вариант. С require() возможно автоматическое применение Code Coverage инструкций без участия бэкэнда.
> а так же позволяет собирать статистику без наглых хаков
Статистика подключений — вызовы require(), профилирование времени инициализации модуля, сбор динамической статистики.
> var r = require;
> r(«pewpew-ololo»);
ну, я там много распинался по поводу того, что именование одной сущности по разному в разных местах — это плохо как для машины, так и для человека. в этом случае любой принцип именования «нас ограничивает», так же как перила ограничивают нас в возможности спрыгнуть с моста и стрелять себе в ноги, чтобы снизить скорость падения)
> тем, что они не должны, по крайней мере, лежать в одном скоупе
а почему бы и нет? изоляция нужна в случае ада вида «два модуля зависят от двух несовместимых версий другого модуля». но мы же не хотим грузить клиенту несколько версий одного модуля, правда? оупенсорс же в конце концов: если что-то не устраивает — почини. и себе жизнь упростишь и остальным.
> кроме времени инициализации, которое нужно замерять в доисторических системах и мобильниках, существуют еще и ресурсы, события, вычисления, которые тянет каждый модуль.
которые вовсе не обязательно выполнять при старте, если в том нет необходимости. хотя да, если либа изначально не ленива, то загрузчик с эвалом в нутрях сделает её ленивой. правда цена — координаты строк будут указывать в стратосферу. и не надо рассказывать про светлое будущее с sourcemap — нам сейчас мучиться)
> Лучше явно чем как-то так автоматически.
автоматически на основе _явной_ декларации использования. $jam.Component — не менее явно, чем require( 'jam/Component' ).
> Максимум документации должно быть в коде — код должен быть самодокументируемым. То, что доки где-то лежат вне файла многим наплевать(не удобно туда-сюда прыгать).
документация должна быть рядом с кодом, но не вперемешку. но это отдельный холивар, который к теме нашего текущего разговора не имеет отношения)
> в require() ленивая загрузка — бонус архитектуры
а у меня бонус фреймворка — модуль $jam.Lazy, который позволяет сделать ленивым не только модуль, но и любую функцию)
> Согласен, просто как вариант. С require() возможно автоматическое применение Code Coverage инструкций без участия бэкэнда.
и всётаки мы скатились до бесполезного спора «а у нас в квартире газ, а нас свой водолаз»). в конце концов всегда можно нагенерировать аннотацию со списком зависимостей, если она всё-таки нужна. у всех разные приоритеты — на том и порешим)
> Статистика подключений — вызовы require(), профилирование времени инициализации модуля, сбор динамической статистики.
ну, ничто не мешает статически трансформировать JAM модули в AMD и обретать все его плюсы и минусы и переключаться между сборками в зависимости от того, что важнее)
основной-то посыл был всё-таки такой:
1. собирать нужно не только js, но и прочие прилагающиеся ресурсы. авторы CJS, AMD и других стандартов упорно про это забывают.
2. не за чем плодить рутину там, где достаточно простого соглашения и нехитрой автоматики.
ты всё-таки попробуй поиграться с примером — просто создаёшь файл, пишешь там код и обновив страницу получаешь его исполнение. при этом грузится только то, что реально используется. это очень удобно и позволяет сконцентрироваться на реализации не отвлекаясь на зависимости.
> r(«pewpew-ololo»);
ну, я там много распинался по поводу того, что именование одной сущности по разному в разных местах — это плохо как для машины, так и для человека. в этом случае любой принцип именования «нас ограничивает», так же как перила ограничивают нас в возможности спрыгнуть с моста и стрелять себе в ноги, чтобы снизить скорость падения)
> тем, что они не должны, по крайней мере, лежать в одном скоупе
а почему бы и нет? изоляция нужна в случае ада вида «два модуля зависят от двух несовместимых версий другого модуля». но мы же не хотим грузить клиенту несколько версий одного модуля, правда? оупенсорс же в конце концов: если что-то не устраивает — почини. и себе жизнь упростишь и остальным.
> кроме времени инициализации, которое нужно замерять в доисторических системах и мобильниках, существуют еще и ресурсы, события, вычисления, которые тянет каждый модуль.
которые вовсе не обязательно выполнять при старте, если в том нет необходимости. хотя да, если либа изначально не ленива, то загрузчик с эвалом в нутрях сделает её ленивой. правда цена — координаты строк будут указывать в стратосферу. и не надо рассказывать про светлое будущее с sourcemap — нам сейчас мучиться)
> Лучше явно чем как-то так автоматически.
автоматически на основе _явной_ декларации использования. $jam.Component — не менее явно, чем require( 'jam/Component' ).
> Максимум документации должно быть в коде — код должен быть самодокументируемым. То, что доки где-то лежат вне файла многим наплевать(не удобно туда-сюда прыгать).
документация должна быть рядом с кодом, но не вперемешку. но это отдельный холивар, который к теме нашего текущего разговора не имеет отношения)
> в require() ленивая загрузка — бонус архитектуры
а у меня бонус фреймворка — модуль $jam.Lazy, который позволяет сделать ленивым не только модуль, но и любую функцию)
> Согласен, просто как вариант. С require() возможно автоматическое применение Code Coverage инструкций без участия бэкэнда.
и всётаки мы скатились до бесполезного спора «а у нас в квартире газ, а нас свой водолаз»). в конце концов всегда можно нагенерировать аннотацию со списком зависимостей, если она всё-таки нужна. у всех разные приоритеты — на том и порешим)
> Статистика подключений — вызовы require(), профилирование времени инициализации модуля, сбор динамической статистики.
ну, ничто не мешает статически трансформировать JAM модули в AMD и обретать все его плюсы и минусы и переключаться между сборками в зависимости от того, что важнее)
основной-то посыл был всё-таки такой:
1. собирать нужно не только js, но и прочие прилагающиеся ресурсы. авторы CJS, AMD и других стандартов упорно про это забывают.
2. не за чем плодить рутину там, где достаточно простого соглашения и нехитрой автоматики.
ты всё-таки попробуй поиграться с примером — просто создаёшь файл, пишешь там код и обновив страницу получаешь его исполнение. при этом грузится только то, что реально используется. это очень удобно и позволяет сконцентрироваться на реализации не отвлекаясь на зависимости.
По поводу «собирать нужно не только js» — согласен.
По поводу рутины — не соглашусь — должно быть явное разделение того, что входит в сборку и что используется.
На крайняк можно заюзать wildcard
Еще каждый модуль может требовать наличие какого-то плагина, что в случае с «бесконфигной» архитектуры влечет за собой всякое колдовство в коде и хтрый его анализ.
И еще я считаю, что модули должны быть гибко абстрагируемы от файловой системы. У тебя завязывается на соглашения по зависимостям, которые, как я понял, ложатся на FS.
На счет общих скоупов не соглашусь — кроме того, что конфликты не исключены еще и каждый объект скоупа увеличивает цену вызова функции, лежащей в этом скоупе.
> ты всё-таки попробуй поиграться с примером
— спасибо, я уже с browserify наигрался =)
Скажи как ты собираешься организовывать локализацию на разные языки, которые могут влеч за собой отключение каких-то фичей? Ну и как делать версии для dev/prod/test? Желательно без копипаста.
По поводу рутины — не соглашусь — должно быть явное разделение того, что входит в сборку и что используется.
На крайняк можно заюзать wildcard
"*": "*.js"
и включить в сборку все модули. Еще каждый модуль может требовать наличие какого-то плагина, что в случае с «бесконфигной» архитектуры влечет за собой всякое колдовство в коде и хтрый его анализ.
И еще я считаю, что модули должны быть гибко абстрагируемы от файловой системы. У тебя завязывается на соглашения по зависимостям, которые, как я понял, ложатся на FS.
На счет общих скоупов не соглашусь — кроме того, что конфликты не исключены еще и каждый объект скоупа увеличивает цену вызова функции, лежащей в этом скоупе.
> ты всё-таки попробуй поиграться с примером
— спасибо, я уже с browserify наигрался =)
$jam.Lazy
— «а у нас в квартире газ, а нас свой водолаз» :) Все подобные фичи это дело времени.Скажи как ты собираешься организовывать локализацию на разные языки, которые могут влеч за собой отключение каких-то фичей? Ну и как делать версии для dev/prod/test? Желательно без копипаста.
> должно быть явное разделение того, что входит в сборку и что используется.
почему должно? одно без другого не имеет смысла. включить модуль в сборку, но нигде им не воспользоваться… зачем? обычно это не надо. а когда надо — всегда можно «воспользоваться» им в *.meta.tree. использовать модуль, не подгрузив его… зачем? код же не будет работать, а будет сыпать ошибками. разве что какой-то хитрый вариант типа «нужный модуль будет подгружен потом другим модулем, чтобы этот модуль мог им воспользоваться» необходимость которого я с трудом представляю.
> На крайняк можно заюзать wildcard "*": "*.js" и включить в сборку все модули.
а если не все из них используются? у меня вот есть условно 2 типа пакетов: библиотеки и приложения. когда собирается приложение — его модули грузятся все, а вот из библиотек только те, что реально используются.
> Еще каждый модуль может требовать наличие какого-то плагина, что в случае с «бесконфигной» архитектуры влечет за собой всякое колдовство в коде и хтрый его анализ.
ничего не влечёт. я плохо акцентировал на этом внимание… автоматика сильно упрощает работу, но она не творит чудеса) если требуется плагин, который регистрируется как, например, функция в инстансе jq. то есть факт его использования в общем случае статически определить сложно, то эту зависимость надо будет определить явно. в meta.tree или же в самом jam.js в комментарии (то есть опуститься до уровня cjs ;). другой вариант — добавить алиас, чтобы обращение к нему удовлетворяло принципам jam:
$jd( '.fancybutton' ).$jq_fancybutton()
но тогда, разумеется, появляется некоторая избыточность обращения.
> И еще я считаю, что модули должны быть гибко абстрагируемы от файловой системы.
а я считаю, что не надо плодить абстракции. знать где лежит модуль, который вот тут вот используется — это классно. а лазить по конфигам в поисках исходника — это бяка.
> каждый объект скоупа увеличивает цену вызова функции, лежащей в этом скоупе
ну там же хэш-таблица. разница незначительна.
> спасибо, я уже с browserify наигрался =)
ну это же совсем не то: о второй уровень из 4 по моей шкале х)
> как ты собираешься организовывать локализацию на разные языки, которые могут влеч за собой отключение каких-то фичей?
хороший вопрос) я пока делал только подмену текстов, но там был отдельный формат для локалей, который собирался также как и все остальные, но на выходе получались собранные бандлы типа index.locale=ru.xml из файлов типа ya_search.locale=ru.xml
думаю можно реализовать аналогичную поддержку «плоскостей сборки» для всех форматов. а ковыряться в конфигах, прописывая каждую локализованную версию файла — совсем не хочется.
> Ну и как делать версии для dev/prod/test?
а это зачем? на мой взгляд разница должна быть настолько минимальной, на сколько это возможно. а если нужны какие-то дополнительные инструменты для дебага — грузить их отдельным пакетом.
почему должно? одно без другого не имеет смысла. включить модуль в сборку, но нигде им не воспользоваться… зачем? обычно это не надо. а когда надо — всегда можно «воспользоваться» им в *.meta.tree. использовать модуль, не подгрузив его… зачем? код же не будет работать, а будет сыпать ошибками. разве что какой-то хитрый вариант типа «нужный модуль будет подгружен потом другим модулем, чтобы этот модуль мог им воспользоваться» необходимость которого я с трудом представляю.
> На крайняк можно заюзать wildcard "*": "*.js" и включить в сборку все модули.
а если не все из них используются? у меня вот есть условно 2 типа пакетов: библиотеки и приложения. когда собирается приложение — его модули грузятся все, а вот из библиотек только те, что реально используются.
> Еще каждый модуль может требовать наличие какого-то плагина, что в случае с «бесконфигной» архитектуры влечет за собой всякое колдовство в коде и хтрый его анализ.
ничего не влечёт. я плохо акцентировал на этом внимание… автоматика сильно упрощает работу, но она не творит чудеса) если требуется плагин, который регистрируется как, например, функция в инстансе jq. то есть факт его использования в общем случае статически определить сложно, то эту зависимость надо будет определить явно. в meta.tree или же в самом jam.js в комментарии (то есть опуститься до уровня cjs ;). другой вариант — добавить алиас, чтобы обращение к нему удовлетворяло принципам jam:
$jd( '.fancybutton' ).$jq_fancybutton()
но тогда, разумеется, появляется некоторая избыточность обращения.
> И еще я считаю, что модули должны быть гибко абстрагируемы от файловой системы.
а я считаю, что не надо плодить абстракции. знать где лежит модуль, который вот тут вот используется — это классно. а лазить по конфигам в поисках исходника — это бяка.
> каждый объект скоупа увеличивает цену вызова функции, лежащей в этом скоупе
ну там же хэш-таблица. разница незначительна.
> спасибо, я уже с browserify наигрался =)
ну это же совсем не то: о второй уровень из 4 по моей шкале х)
> как ты собираешься организовывать локализацию на разные языки, которые могут влеч за собой отключение каких-то фичей?
хороший вопрос) я пока делал только подмену текстов, но там был отдельный формат для локалей, который собирался также как и все остальные, но на выходе получались собранные бандлы типа index.locale=ru.xml из файлов типа ya_search.locale=ru.xml
думаю можно реализовать аналогичную поддержку «плоскостей сборки» для всех форматов. а ковыряться в конфигах, прописывая каждую локализованную версию файла — совсем не хочется.
> Ну и как делать версии для dev/prod/test?
а это зачем? на мой взгляд разница должна быть настолько минимальной, на сколько это возможно. а если нужны какие-то дополнительные инструменты для дебага — грузить их отдельным пакетом.
> нужный модуль будет подгружен потом другим модулем, чтобы этот модуль мог им воспользоваться
У тебя архитектура предполагает факт того, что логика приложения может динамически расширятся?
> гибко абстрагируемы от файловой системы
хороший тому пример
> ну там же хэш-таблица. разница незначительна
При каждом вызове функции скоуп функции пересоздается. Это, конечно, копейки, но в некоторых случаях и копейка важна — тормозные браузеры, горячие функции, время-зависимые приложения (спиддиал например)
> прописывая каждую локализованную версию файла
И тут в тред врывается абстракция над файловой системой и наследование конфигов! ;-)
> разница должна быть настолько минимальной, на сколько это возможно
Тут минимум dev — один хост бэкэнда, test — другой. Ну и всякие хитрые оптимизации production-сборки.
У тебя архитектура предполагает факт того, что логика приложения может динамически расширятся?
> гибко абстрагируемы от файловой системы
хороший тому пример
"i18n": "ru.json"
и "i18n": "en.json"
> ну там же хэш-таблица. разница незначительна
При каждом вызове функции скоуп функции пересоздается. Это, конечно, копейки, но в некоторых случаях и копейка важна — тормозные браузеры, горячие функции, время-зависимые приложения (спиддиал например)
> прописывая каждую локализованную версию файла
И тут в тред врывается абстракция над файловой системой и наследование конфигов! ;-)
> разница должна быть настолько минимальной, на сколько это возможно
Тут минимум dev — один хост бэкэнда, test — другой. Ну и всякие хитрые оптимизации production-сборки.
> У тебя архитектура предполагает факт того, что логика приложения может динамически расширятся?
сама по себе? нет) вся логика должна быть задекларирована программистом, протестирована тестировщиком и раскатана по cdn-у) это если говорить абстрактно. а конкретно — не должно быть никаких висячих зависимостей. глупо делать так, чтобы фреймворк зависел от опционального плагина. или я что-то не улавливаю?
> хороший тому пример «i18n»: «ru.json» и «i18n»: «en.json»
пример чего? я могу отвечать только раз в сутки, так что переспрашивать не очень удобно
> Это, конечно, копейки, но в некоторых случаях и копейка важна
сферическая копейка в вакууме конечно важна, но на практике бутылочные горлышки находятся в совсем других местах
> спиддиал например
тоже занимался спиддиалом?) пример, кстати, показательный. знаешь что позволяет визуальным закладкам от яндекса открываться быстрее любых других? пререндер вкладки.
> И тут в тред врывается абстракция над файловой системой и наследование конфигов! ;-)
фс — сама по себе уже достаточно неплоха абстракция древовидной структуры и незачем лепить сверху практически то же самое, но со своими праилами блекджека. линух на этом основан. а у меня нет конфигов и нечего не надо наследовать: Р
> Тут минимум dev — один хост бэкэнда, test — другой. Ну и всякие хитрые оптимизации production-сборки.
а что мешает использовать тот хост с которого загружена страница? я бы побоялся выкладывать на продакшен не тестированный код. отличие даже в один небольшой файл может вылиться в серьёзные проблемы.
сама по себе? нет) вся логика должна быть задекларирована программистом, протестирована тестировщиком и раскатана по cdn-у) это если говорить абстрактно. а конкретно — не должно быть никаких висячих зависимостей. глупо делать так, чтобы фреймворк зависел от опционального плагина. или я что-то не улавливаю?
> хороший тому пример «i18n»: «ru.json» и «i18n»: «en.json»
пример чего? я могу отвечать только раз в сутки, так что переспрашивать не очень удобно
> Это, конечно, копейки, но в некоторых случаях и копейка важна
сферическая копейка в вакууме конечно важна, но на практике бутылочные горлышки находятся в совсем других местах
> спиддиал например
тоже занимался спиддиалом?) пример, кстати, показательный. знаешь что позволяет визуальным закладкам от яндекса открываться быстрее любых других? пререндер вкладки.
> И тут в тред врывается абстракция над файловой системой и наследование конфигов! ;-)
фс — сама по себе уже достаточно неплоха абстракция древовидной структуры и незачем лепить сверху практически то же самое, но со своими праилами блекджека. линух на этом основан. а у меня нет конфигов и нечего не надо наследовать: Р
> Тут минимум dev — один хост бэкэнда, test — другой. Ну и всякие хитрые оптимизации production-сборки.
а что мешает использовать тот хост с которого загружена страница? я бы побоялся выкладывать на продакшен не тестированный код. отличие даже в один небольшой файл может вылиться в серьёзные проблемы.
> чтобы фреймворк зависел от опционального плагина
Тут я про линивую загрузку модулей.
> пример чего
Пример абстракции над файловой системой
> Это, конечно, копейки, но в некоторых случаях и копейка важна
Недавно буквально наткнулись на такую проблему (плагины для браузра) без ленивой загрузки и без прогретого JIT он стартует 150 мс (ну очень тяжелый), а с ленивой загрузкой 20мс
> тоже занимался спиддиалом?
Консультировал по оптимизации визуальных закладок 2,0.
> а у меня нет конфигов и нечего не надо наследовать
ок
> тот хост с которого загружена страница
особенность архитектуры, часто не мы решаем какая она должна быть (адрес бэкнда другой у дева и продакшена)
Что-то у нас тред разросся :) Понаписали уже больше чем в статье.
Тут я про линивую загрузку модулей.
> пример чего
Пример абстракции над файловой системой
> Это, конечно, копейки, но в некоторых случаях и копейка важна
Недавно буквально наткнулись на такую проблему (плагины для браузра) без ленивой загрузки и без прогретого JIT он стартует 150 мс (ну очень тяжелый), а с ленивой загрузкой 20мс
> тоже занимался спиддиалом?
Консультировал по оптимизации визуальных закладок 2,0.
> а у меня нет конфигов и нечего не надо наследовать
ок
> тот хост с которого загружена страница
особенность архитектуры, часто не мы решаем какая она должна быть (адрес бэкнда другой у дева и продакшена)
Что-то у нас тред разросся :) Понаписали уже больше чем в статье.
> Тут я про ленивую загрузку модулей.
в том-то и дело, что ленивая нужна загрузка не модулей, а пакетов. иначе будет 100500 запросов.
> Пример абстракции над файловой системой
а, пример определения модуля i18n как алиаса на один из конкретных файлов? а что делать в случае, когда в какой-нибудь турецкой локали не хватает нужных строк? тут нужно не просто «всё решать одной абстракцией» — тут надо парсить локали и собирать сборную солянку. либо громко ругаться, что не хватает переводов. но уж точно не просто заменять один файлик на другой.
> Недавно буквально наткнулись на такую проблему (плагины для браузра) без ленивой загрузки и без прогретого JIT он стартует 150 мс (ну очень тяжелый), а с ленивой загрузкой 20мс
я.бар?) ну, вообще говоря, да, специфика плагинов в том, что подгрузка модулей из памяти не даёт такого пенальти, как подгрузка с сервера, зато есть куча левого функционала, который практически не используется. поэтому для мозиллы, например, я написал клёвый ленивый загрузчик (https://github.com/nin-jin/fenix-snippet#%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8F%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) — кстати, хороший пример, ленивой загрузки и изоляции модулей, оставаясь при этом в рамках PMS. правда ценой типовой шапки из нескольких строк: подключение загрузчика и подключение каждого необходимого пакета, модули из которых грузятся уже лениво.
> Консультировал по оптимизации визуальных закладок 2,0.
под какой браузер? и какие выводы?
> особенность архитектуры, часто не мы решаем какая она должна быть (адрес бэкнда другой у дева и продакшена)
и всё же, ошибки в архитектуре тоже надо исправлять, иначе есть риск погрязнуть в костылях.
> Что-то у нас тред разросся :) Понаписали уже больше чем в статье.
автор нас наверно уже проклял, сглазил и навёл порчу х)
в том-то и дело, что ленивая нужна загрузка не модулей, а пакетов. иначе будет 100500 запросов.
> Пример абстракции над файловой системой
а, пример определения модуля i18n как алиаса на один из конкретных файлов? а что делать в случае, когда в какой-нибудь турецкой локали не хватает нужных строк? тут нужно не просто «всё решать одной абстракцией» — тут надо парсить локали и собирать сборную солянку. либо громко ругаться, что не хватает переводов. но уж точно не просто заменять один файлик на другой.
> Недавно буквально наткнулись на такую проблему (плагины для браузра) без ленивой загрузки и без прогретого JIT он стартует 150 мс (ну очень тяжелый), а с ленивой загрузкой 20мс
я.бар?) ну, вообще говоря, да, специфика плагинов в том, что подгрузка модулей из памяти не даёт такого пенальти, как подгрузка с сервера, зато есть куча левого функционала, который практически не используется. поэтому для мозиллы, например, я написал клёвый ленивый загрузчик (https://github.com/nin-jin/fenix-snippet#%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8F%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F) — кстати, хороший пример, ленивой загрузки и изоляции модулей, оставаясь при этом в рамках PMS. правда ценой типовой шапки из нескольких строк: подключение загрузчика и подключение каждого необходимого пакета, модули из которых грузятся уже лениво.
> Консультировал по оптимизации визуальных закладок 2,0.
под какой браузер? и какие выводы?
> особенность архитектуры, часто не мы решаем какая она должна быть (адрес бэкнда другой у дева и продакшена)
и всё же, ошибки в архитектуре тоже надо исправлять, иначе есть риск погрязнуть в костылях.
> Что-то у нас тред разросся :) Понаписали уже больше чем в статье.
автор нас наверно уже проклял, сглазил и навёл порчу х)
Да нет, мне, наоборот, приятно, что мой скромный пост вызвал такую дискуссию.
Отдельные модули можно кэшировать в localStorage, а загрузка сборок — overhead.
> либо громко ругаться, что не хватает переводов. но уж точно не просто заменять один файлик на другой.
Так и делается. Берется сервис переводов(который ругается на непереведенные штуки) с него все сливаем в один файл, затем натравливаем локализатор и вуаля. Ну тут уже дело не в том как организуется этот процесс, а в том сколько нужно накопипастить без наследования конфигов.
> какие выводы
прогревать все функции (для JIT) и хранить в расшаренной области.
> ошибки в архитектуре тоже надо исправлять
это не ошибка, а особенность (не всегда бывает возможно стучаться к локалдомену)
> либо громко ругаться, что не хватает переводов. но уж точно не просто заменять один файлик на другой.
Так и делается. Берется сервис переводов(который ругается на непереведенные штуки) с него все сливаем в один файл, затем натравливаем локализатор и вуаля. Ну тут уже дело не в том как организуется этот процесс, а в том сколько нужно накопипастить без наследования конфигов.
> какие выводы
прогревать все функции (для JIT) и хранить в расшаренной области.
> ошибки в архитектуре тоже надо исправлять
это не ошибка, а особенность (не всегда бывает возможно стучаться к локалдомену)
оверхед — это 100500 хттп запросов и как следствие лишние задержки. а кеширование в ls — ещё один костыль, не добавляющий ни надежности ни поддерживаемости.
тут нужно наследование локалей. и не через какой-то там сервис, а прямо тут, при разработке. и не конфигов, а самих локализованных строк. или строки у тебя в конфигах? для каждого модуля?
для jit функции и сами прогреются когда надо будет. на то он и jit. ускорять работу одной фичи путём торможения работы всего браузера — не самая светлая идея. если все будут считать себя пупами земли и прогревать себя при старте — браузер будет стартовать как старичок нетскейп. ну или тупить первую минуту, как винда.
а в каких случаях таких возможностей нет?
тут нужно наследование локалей. и не через какой-то там сервис, а прямо тут, при разработке. и не конфигов, а самих локализованных строк. или строки у тебя в конфигах? для каждого модуля?
для jit функции и сами прогреются когда надо будет. на то он и jit. ускорять работу одной фичи путём торможения работы всего браузера — не самая светлая идея. если все будут считать себя пупами земли и прогревать себя при старте — браузер будет стартовать как старичок нетскейп. ну или тупить первую минуту, как винда.
а в каких случаях таких возможностей нет?
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Модульный подход к разработке web-приложений с использованием JavaScript: AMD и RequireJS