Javascript-форум (https://javascript.ru/forum/)
-   Библиотеки/Тулкиты/Фреймворки (https://javascript.ru/forum/library-toolkit-framework/)
-   -   кто что использует для модульности скриптов? (https://javascript.ru/forum/library-toolkit-framework/18684-kto-chto-ispolzuet-dlya-modulnosti-skriptov.html)

vflash 11.07.2011 16:07

кто что использует для модульности скриптов?
 
есть проект(в вакууме) у него 3...100 js файлов. вопрос как организовать это хозяйство ? кто что использует и как бы вы не стали делать.

также:
стоит ли давать алиасы файлам(модулям) ?
отношение к отложенной загрузки ? это когда скрипты в конце загрузки страницы постепенно подгружаются, пример hh.ru

Kolyaj 11.07.2011 16:21

Цитата:

Сообщение от vflash
кто что использует

https://github.com/Kolyaj/BuildJS

vflash 11.07.2011 16:34

Kolyaj,
так понял каждый рас формируется один файл. а как в разработке понять в каком файле произошла ошибка ?

Kolyaj 11.07.2011 17:02

По строкам с ошибкой, в общем-то, понятно. Они ж редко сами по себе возникают, где правишь код, там и возникают.

vflash 11.07.2011 17:43

к сожалению не всегда там где правишь. от таких плюшек жалко отказываться

Kolyaj 11.07.2011 17:48

Можно в собранный файл добавлять информацию о том, где какой файл начинается и заканчивается. Мне это не надо было, я не делал.

tenshi 14.07.2011 12:01

я организую так: все файлы группируются по модулям, а модули по пакетам. специальный сборщик при запросе страницы, сканирует директорию и составляет для каждого пакета:
index.js, который по очереди подключает все скрипты из пакета
compiled.js, который содержит все скрипты одним файлом
index.css, со ссылками на страницы стилей
page_*.css, cо ссылками на сами файлы стилей
compiled.css - все стили одним файлом

при разработке соответственно подключаются индексы, а на продакшен идут скомпилленые версии

tenshi 14.07.2011 12:07

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

не надо писать тонны кода и не придётся заморачиваться с отложенной загрузкой. лучше если скрипты и стили подгрузятся сразу и страница будет работоспособной и хорошо выглядящей.

tenshi 14.07.2011 12:13

вот, наваял за вечер простенькое приложение: Snippet!, а вот пакет для него

vflash 14.07.2011 14:24

Цитата:

Сообщение от tenshi
ение: Snippet!, а во

ссылка битая

tenshi 14.07.2011 14:28

чорд >< поправил

kobezzza 14.07.2011 15:01

Я делаю так: для каждого типа страницы есть свой класс в котором указаны все методы для данного типа, конструктор класса вешает необходимые обработчики и т.д.

Также есть отдельный скрипт который в зависимости от URL страницы создаёт тот или иной необходимый экземпляр и делает различные дополнительные операции.

Потом всё сжимаю через Closure Compiler и заливаю одним файлом.

Как тестить: Google Closure Compiler может при компиляции создавать Source Map - это такой файл который осуществляет связь между сжатым и несжатым файлом и теперь при ловле ошибок можно загрузить этот файл в Firebug (необходим доп. плаг) и вуаля!

Также никто не отменял конструкции throw, try/catch/finally и т.д.

tenshi 14.07.2011 15:07

пока разрабатываешь под фф никто не отменял, а вот когда бьёшься с ними в других браузерах - хочется проклинать всё и вся

vflash 14.07.2011 16:10

tenshi, не много ли with ? )

tenshi 14.07.2011 16:27

не, самый раз. а что? %-)

vflash 14.07.2011 16:43

https://developer.mozilla.org/en/Jav...tatements/with
Цитата:

Using with is not recommended, and is forbidden in ECMAScript 5 strict mode. The recommended alternative is to assign the object whose properties you want to access to a temporary variable.

tenshi 14.07.2011 16:54

и чо? от их сугубо личного мнения данная конструкция работать не перестаёт. я не хочу для каждого класса писать один и тот же префикс или явно импортировать десятки переменных в локальный контекст, только лишь потому, что какие-то остолопы решили, что нефиг хомячкам пользоваться гранатами.

kobezzza 14.07.2011 20:40

Ну я бы не назвал остолопами тех людей, которые не рекомендуют использовать with) Например Дуглас Крокфорд или Илья Кантор (основатель этого сайта). Помимо неочевидности with он несёт в себе большой минус - код с with не жмётся (или жмётся с помощью игнора with, но ето не гуд) минификаторами.

tenshi 14.07.2011 22:04

он замечательно жмётся гзипом. а то о чём ты говоришь - это обфускация. удел параноиков.

kobezzza 14.07.2011 22:08

Ну вообщето, тот же Closure Compiler анализирует код, и сжимает его так, чтобы + Gzip был выигрыш в объёме (причём оч крутой). так что извини, но ты не прав.

А если уж стоит вопрос обфускации, то лучше юзать Packer)

Пример на Closure Compiler:
До сжатия:
function hello(name) {
alert('Hello, ' + name);
}
hello('New user');

После:
alert("Hello, New user");

Он проанализировал код, и вычислил, что в данном случае можно сделать без всяких функций) Так что минификаторы не так просто работают...

tenshi 15.07.2011 00:12

не фантазируй. крутого выигрыша в объёме зипованного текста быть не может.

а потом на странице вставляем такой код <button onclick="hello('Привет!')"> и чешем репу. а потом получаем жалобу в саппорт со скриншотом консоли ошибок и теряемся в догадках. а потом обнаруживаем странные глобальные переменные, созданные этим чудом для своих нужд. вам геморроя мало?

kobezzza 15.07.2011 00:26

Во первых: при стандартном сжатии глобальные переменные не жмуться и ваш пример будет прекрасно работать;
Во вторых: привязка событий из HTML - моветон, сущности должны быть разделены;
В третьих: короткие имена переменных в JS работают быстрее (да, это факт);
В четвёртых: минификатор не создаёт дополнительных переменных;
В пятых: чтобы тестить сжатый код многие минификаторы создают source map, который показывает ошибку в несжатом варианте;
В шестых: real-тест jQuery с минификатором и без (Closure Compiler: Simple сжатие):
Original Size: 	211.02KB (62.58KB gzipped)
Compiled Size: 	88.7KB (31.26KB gzipped)


Не веришь? http://closure-compiler.appspot.com/home - пробуй сам

Конечно, если сравнивать сжатие на варианте без пробелов, табуляций, новых строк и комментов, то разница килобайт 6, но ведь в реальной жизни никто не пишет код в 1-у строку и без комментов ;)

Ну и наконец, то, что так делают крупнейшие компании на своих сайтах и так делают отцы JS наталкивает на мысль, что это действительно того стоит.

tenshi 15.07.2011 08:25

1. это не мой пример, а твой. ты признаёшь, что наврал?
2. они и разделены. поведение вынесено в функцию.
3. ага, на целые сотые доли микросекунд х)
4. минификатор может и нет, а вот gcc - да. тут чел на форуме недавно жаловался.
5. ага, придумали себе грабли, а потом костыли, чтобы грабли не сильно били х) по секрету скажу, что ие даже строку не всегда правильно указывает. что уж говорить про номер символа. а минификаторы пренепременно всё в одну строку пихают.
5. а теперь фокус-покус: просто вырезаем все комментарии и получаем 40кб

хороший код не нуждается в комментариях. разве что по самому минимуму, а не как в джквери:
Цитата:

// Used for trimming whitespace
trimLeft = /^\s+/,
trimRight = /\s+$/,

// Check for digits
rdigit = /\d/,

// Match a standalone tag
rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
ага, толпа леммингов не может ошибаться х)

kobezzza 15.07.2011 08:56

Цитата:

1. это не мой пример, а твой. ты признаёшь, что наврал?
Нет, т.к. в случае будь пример в локали, то всё бы так и было.

Цитата:

2. они и разделены. поведение вынесено в функцию.
Это не разделение, а бред и вообще хорошая практика - это делегирование.

Цитата:

3. ага, на целые сотые доли микросекунд х)
с миру по нитке...

Цитата:

4. минификатор может и нет, а вот gcc - да. тут чел на форуме недавно жаловался.
- хз, ни разу проблем не было

Цитата:

5. ага, придумали себе грабли, а потом костыли, чтобы грабли не сильно били х) по секрету скажу, что ие даже строку не всегда правильно указывает. что уж говорить про номер символа. а минификаторы пренепременно всё в одну строку пихают.
- ни разу проблем не было

Цитата:

хороший код не нуждается в комментариях. разве что по самому минимуму, а не как в джквери:
Плачу) Т.е. не нужно описывать входные параметры методов, что они возвращают и т.д.? И я последнее время часто слышу "код jQuery ужасен!!!!", но ни разу никто не сказал почему, секрет?)

Цитата:

ага, толпа леммингов не может ошибаться х)
Ну ок, ты гуру, местный аналог Чака Норриса, куда всем до тебя :D

tenshi 15.07.2011 10:01

1. не было бы. как минимум потому, что в ие функция по любому стала бы глобальной :Р

2. это не бред, а правда жизни. слои не могут быть полностью изолированы, так как им надо общаться между собой. так что либо функции завязываются на идентификаторы/классы, либо вёрстка на имена функций. один фиг.

3. нищему гора мусора, ибо из кусочков ниток заебёшься шить рубашку, да и получится нечто страшное. оптимизировать надо то, что тормозит, а не что попало. а то получается наворотят мегатонны говнокода, а потому, чтобы это не тормозило вместо рефакторинга шарятся по полу в поисках ниточек

4, 5. ну я рад за тебя, чо. пока петух не клюнет - все уверены, что в консерватории тишь и благодать.

6. а зачем это описывать?
attr: function( name, value )
- что тут комментировать?
ну вот и спроси у джона, почему он считает свой код ужасным. наверно потому, что его тяжело поддерживать.

7. то есть кроме как примазаться к авторитетам ты ничего не можешь? детский сад. лет 5 назад все бредили xhtml и каждый "гуру" писал статьи как отрезать себе конечности, но ущемиться-таки к xhtml. потом ветер поменялся и теперь все бредят html5 и плюются на необходимость закрывать тэги, но продолжают щемиться теперь уже в html5. так и будешь хвостиком бегать за попсовыми блоггерами или может начнёшь трезво оценивать ситуацию? минификация, афайк, не даёт практически никаких бенефитов, зато даёт кучу лишних телодвижений. заняться больше не чем, как считать байтики и микросекунды?

kobezzza 15.07.2011 10:20

Цитата:

1. не было бы. как минимум потому, что в ие функция по любому стала бы глобальной :Р
Причём тут ИЕ я не понял, минификатор не привязан к браузеру.

Цитата:

2. это не бред, а правда жизни. слои не могут быть полностью изолированы, так как им надо общаться между собой. так что либо функции завязываются на идентификаторы/классы, либо вёрстка на имена функций. один фиг.
Извини, но не "один" фиг. Привязка к вёрстке гораздо более универсальная.

Цитата:

3. нищему гора мусора, ибо из кусочков ниток заебёшься шить рубашку, да и получится нечто страшное. оптимизировать надо то, что тормозит, а не что попало. а то получается наворотят мегатонны говнокода, а потому, чтобы это не тормозило вместо рефакторинга шарятся по полу в поисках ниточек
Почему нельзя оптимизировать то, что занимает по времени меньше секунды (в плане сложности реализации), но даёт бонус? Я бы с тобой согласился, если бы минификация была бы чем-то нереально тяжёлым...

Цитата:

4, 5. ну я рад за тебя, чо. пока петух не клюнет - все уверены, что в консерватории тишь и благодать.
Я тоже за себя рад.

Цитата:

6. а зачем это описывать?
attr: function( name, value )
А теперь прикинь класс для работы с WebGL, там функции с кучей параметров, которые ну не фига не очевидны не набившему шишек прогеру (к томуже нуно хорошо шарить в стереометрии).

Цитата:

7. то есть кроме как примазаться к авторитетам ты ничего не можешь? детский сад. лет 5 назад все бредили xhtml и каждый "гуру" писал статьи как отрезать себе конечности, но ущемиться-таки к xhtml. потом ветер поменялся и теперь все бредят html5 и плюются на необходимость закрывать тэги, но продолжают щемиться теперь уже в html5. так и будешь хвостиком бегать за попсовыми блоггерами или может начнёшь трезво оценивать ситуацию? минификация, афайк, не даёт практически никаких бенефитов, зато даёт кучу лишних телодвижений. заняться больше не чем, как считать байтики и микросекунды?
В отличии от некоторых, у меня нету "звёздной болезни" и если ты считаешь, что прислушивание к мнениям более опытных людей - это подмазывание, то извини, но ты просто глупец.

Какие лишние телодвижения? Я запускаю 1 bat файл, который отрабатывает за микросекунды, но при этом объединяет файлы, сжимает код и проверяет на лексические ошибки.

melky 15.07.2011 14:09

вы отдалились от темы (прочитайте её имя). Мне кажется, хватит.

tenshi 17.07.2011 12:44

1. при том, что такой способ определения функции всегда создаёт глобальную функцию в jscript

2. с чего бы? один скрипт обслуживающий десяток разных страниц - куда более частая ситуация, чем одна страница обслуживающая десяток сприптов (какая-то странная страница о0). поэтому вполне нормально, что вёрстка подстраивается под скрипты, а не наоборот.

3. она увеличивает общую сложность системы (например, нам YUI компрессор портил css-ки - пришлось писать костыли), усложняет отладку (фиг ты на продакшене поймёшь где ошибка), увеличивает время сборки (а когда дедлайн на носу, итерации релизного тестирования могут быть очень короткими)

6. поэтому давайте всунем в jsdoc-и полный курс стереометрии? х) не надо писать функции с кучей параметров и всё будет хорошо. разумеется, если писать говнокод, то без комментов никак.

7. то есть ты признаёшь, что своих мозгов тебе не хватает и поэтому не имея собственного мнения ты пропагандируешь идеи тех у кого учился?

8. а батничек сам появился? а тулза для минификации сама поставилась? а муки выбора тулзы не мучали? ты потратил на это своё время. бесполезно потратил. и теперь всем, кто будет работать с этим кодом после тебя придётся настраивать у себя всё окружение на которое ты завязался в своём коде. пример с jq показателен. автор сидит на линухе и юзает мэйкфайлы. у него всё хорошо. а вот чтобы собрать его под виндой надо шаманить с сигвином. нельзя просто поставить какой-нибудь питон и запустить make.py. нет, надо поставить эмулятор линуха, прикрутить сборщики css и js, и писать собственный батничек, чтобы не лазить каждый раз в консоль. хорошо, что он хотябы не заюзал какой-нибудь node-js, которого нету под винду, но некоторые и этим не гнушаются.

melky, не указывай нам что делать и мы не скажем куда тебе пойти ;-)

trikadin 17.07.2011 14:20

tenshi, воу-воу-воу! JScript?

Kolyaj 17.07.2011 17:56

Цитата:

Сообщение от tenshi
1. при том, что такой способ определения функции всегда создаёт глобальную функцию в jscript

Не создаёт. Я, конечно, понимаю, с чем ты попутал, но и там создаётся не глобальная, а в текущем контексте.


Цитата:

Сообщение от trikadin
tenshi, воу-воу-воу! JScript?

А что не так?

trikadin 17.07.2011 18:20

JScript != JavaScript

Kolyaj 17.07.2011 18:36

А не так-то что? tenshi пишет про IE, в IE JScript.

tenshi 23.07.2011 16:49

trikadin, JScript != Javascript != ECMAScript != ActionScript != CoffeeScript и чо?

Kolyaj, угу, с мозилловыми стейтментами спутал .-.

x-yuri 29.07.2011 08:17

Цитата:

Сообщение от tenshi
Kolyaj, угу, с мозилловыми стейтментами спутал .-.

а о каких стейтментах речь?

Octane 29.07.2011 08:27

Цитата:

Сообщение от x-yuri
а о каких стейтментах речь?

(function func() {

   alert(typeof func); // это кстати вместо arguments.callee в ECMAScript 5 предлагают использовать

}());
alert(typeof func); // в старых IE здесь будет функция

tenshi 29.07.2011 09:31

if (true) {
  function a() {
    alert(1);
  }
} else {
  function a() {
    alert(2);
  }
}
a();

x-yuri 29.07.2011 12:22

хм, не назвал бы ie 8 старым...

DjDiablo 13.09.2011 20:04

Мой подход. Правда он для интернет приложений более актуален, чем для сайтов.

1) из глобальных переменных нужен только один нейм спейс. Все остальные нейм спейсы и переменные внутри главного. Это однозначно - иначе при расширении могут возникнуть траблы. В лице нечайного изменения сторонним модулем кому нибудь нужной глобальной переменной.

2) Один компонент один класс/обьект. К примеру в одном обьекте можешь разместить информацию о бизнес обьекте, и методы модификации этой информации. Помоему этот паттерн эксперт называется. Я стараюсь им максимально пользоваться. Желательно чтобы разные компоненты были как можно меньше связаны.

3) Если не знаешь будет ли существовать компонент или нет. Используй систему сообщений для реализации слабого связывания. В отличии от прямого вызова, отсутствие компонента не приведёт к ошибке.

4) Если проект действительно сложный и большой, то не надо упаковывать всё в один файл. Лучше упаковать блоки функциональности по отдельности. Ядро отдельно. Админка отдельно , cтраница с товарами отдельно. Это есть смысл сделать хотябы потому что вряд ли все модули потребуются сразу. И грузить их разом накладно по времени. К приеру для админки. Админка + ядро. Для товаров Товары+ ядро и тд.

5) Желательно разбить всё приложение на 3 части пресловутый MVC. Это облегчит сопровождение.
А) слой Present ответственный за интерфейс.
Б) слой ответственный за логику самого приложения
В) Слой ответственный за данные. (мне он нужен редко если
честно, так как я стараюсь групировать данные и методы в бизнес слое) Это свёртыванием слоёв называется, и это нормальная. практика. Так что не надо ля-ля )))

6) Инициализируй все компоненты из которых состоит приложение в одном месте.

7) можно сделать что-то вроде. GetModule ("список модулей",function(){
действия по инициализации компонента. после загрузки модулей.
get Module должен проверять загружались ли требуемые модули уже. и если нет то грузить
});
Помоему во всех загрузчиках эта возможность уже предусмотрена. labJS к примеру.

x-yuri 15.09.2011 10:08

Цитата:

Сообщение от DjDiablo
1) из глобальных переменных нужен только один нейм спейс. Все остальные нейм спейсы и переменные внутри главного. Это однозначно - иначе при расширении могут возникнуть траблы. В лице нечайного изменения сторонним модулем кому нибудь нужной глобальной переменной.

и толку от этого неймспейса, если он по сути становится новой глобальной областью видимости?

Цитата:

Сообщение от DjDiablo
2) Один компонент один класс/обьект. К примеру в одном обьекте можешь разместить информацию о бизнес обьекте, и методы модификации этой информации. Помоему этот паттерн эксперт называется. Я стараюсь им максимально пользоваться. Желательно чтобы разные компоненты были как можно меньше связаны.

не нашел такого паттерна и похоже, что речь идет о том, что следует стремиться к слабой связанности (coupling) и сильной связности (cohesion). Я бы только добавил, что надо задумываться о необходимости связей, а не избегать их любой ценой. Потому что есть обратная сторона медали: чем меньше связей, тем сложнее код.

Цитата:

Сообщение от DjDiablo
5) Желательно разбить всё приложение на 3 части пресловутый MVC. Это облегчит сопровождение.
А) слой Present ответственный за интерфейс.
Б) слой ответственный за логику самого приложения
В) Слой ответственный за данные. (мне он нужен редко если
честно, так как я стараюсь групировать данные и методы в бизнес слое)

приведи пример приложений, где это нужно

Цитата:

Сообщение от DjDiablo
Это свёртыванием слоёв называется, и это нормальная. практика. Так что не надо ля-ля )))

где об этом можно почитать?

Цитата:

Сообщение от DjDiablo
6) Инициализируй все компоненты из которых состоит приложение в одном месте.

почему мне не достаточно знать, где что инициализируется, почему мне нужно засунуть это в одно место?

DjDiablo 15.09.2011 15:06

1)
Цитата:

и толку от этого неймспейса, если он по сути становится новой глобальной областью видимости?
Он нестановится новой глобальной областью видимости! Если админ подключит к сайту быдло плагин у которого имя переменной совпадает с твоей, то твой код останется работать. Потому что твоя переменная в своём неймспейсе. и вторая причина Ты можешь раскидать код по неймспейсам код, и тем самым упростить работу с ним.

2) 3.1.4 Информационный эксперт (Information Expert)- GRASP

6)
Цитата:

почему мне не достаточно знать, где что инициализируется, почему мне нужно засунуть это в одно место?
допустим функционал каждого модуля инициализируется в $("document").ready(function(){
инициализация компонента.
});

где гарантия того что все твои ready будут вызываться в нужно тебе порядке ? Лично для меня, невовремя включающиеся модули превратились в реальный геморой.
поэтому в модуле initJs который загружается последним. Есть код

$("document").ready(function(){
    wr.icon.init();       //инициализация 1го модуля
    wr.arranger.init();//инициализация 2го модуля
    wr.history.init();   //инициализация 3го модуля
    wr.inteface.init();  //инициализация 4го модуля
});

соответственно в каждом модуле есть свой метод init.

initJs - стал централизованным местом управления инициализацией приложения. Те модули которые в инициализации в определённом порядке не нуждаются, я неотслеживаю. Впрочем есть и противоположенный подход можно перечислить необходимые модули, прямо


Часовой пояс GMT +3, время: 02:27.