Обновить
256K+

JavaScript *

Прототипно-ориентированный язык программирования

285,49
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Черные дыры при разработке Веб проекта

Время на прочтение14 мин
Охват и читатели9.4K
Речь пойдет о PHP,JavaScript и MySQL как стартовой точке. Я также приведу некоторые цифры тестов производительности и потери времени, которые могут убить проект, на примере одного из продуктов, которые мне пришлось недавно вскрыть на предмет поиска проблемных мест, и покажу как можно в три шага убить проект.



Предисловие.


Недавно мне была поставлена задача, помочь найти проблемы в одном из веб проектов, созданных как обычно на PHP+MySQL, и все это кроме того завернуто в Symfony Framework. База данных начала сильно расти, так-как люди собирали эвенты поведения (допустим автопарка) которые вливались буквально каждые 5 минут. Естественно таблица эвентов выросла, и дабы MySQL с ней хоть как то справлялась, ее разбили на партиции. В итоге все это сводилось к разного рода выборкам и отчетам, т.е. аналитике. В итоге, даже простая выборка за период, плюс небольшой подсчет, занимали от 11 сек и выше. Видимо поэтому и было принято решение, ограничивать выбираемый период в днях.

Читать дальше →

Мобильные браузеры и position:fixed

Время на прочтение4 мин
Охват и читатели39K
CSS-свойство position:fixed в Mobile Safari сносно работает начиная c iOS 5. В Android родной браузер частично понимает это свойство начиная с версии системы 2.1, адекватно — с 2.2, полная поддержка — с 3.0. Подробнее: таблица поддержки position:fixed.

HTML:
<div id="topbar">Fixed Title</div>
<div id="content">
	<h2>Start</h2>
	<p>Main content text </p>
	...
	<p>Main content text </p>
	<h2>End</h2>
</div>
<div id="bottombar">Fixed footer</div>

CSS:
#content{
	padding: 50px 0; /* отбиваем высоту баров, чтобы не перекрывать контент вверху и внизу страницы */
}
#topbar,
#bottombar {
	position: fixed;
	left: 0;
	width:100%;
	height: 50px; /* фиксируем высоту для простоты */
	line-height:50px;
	background:#eee;
	text-align: center;
}
#topbar {top: 0;}
#bottombar {bottom: 0;}


Теперь в современных смартах у нас topbar и bottombar «прибиты» соответственно к верху и к низу окна. Проблема позицонирования при первом скролле в iOS решается мини-Javacript'ом (исправлено):
window.scrollBy(0, 1);

А как быть со старичками?

Вышло обновление JavaScript шаблонизатора ECT

Время на прочтение3 мин
Охват и читатели6K
Ровно три месяца назад я представил хабрасообществу JavaScript шаблонизатор ECT. Вчера для него вышло обновление, о котором я хочу рассказать в этой статье.

Вы знакомы с ECT?


ECT это JavaScript шаблонизатор со встроенным CoffeeScript синтаксисом (отсюда и название: Embedded CoffeeScript Templates). ECT изначально разрабатывался с упором на максимальную производительность и при этом он предоставляет разработчику богатый набор функций.

Что нового?

Читать дальше →

Мысли по процессу разработки игры REFLECT

Время на прочтение2 мин
Охват и читатели5.7K
Доброго времени суток, пользователи хабрахабра. В ответ на инициативу по разработке игры REFLECT мне захотелось выразить несколько мыслей по поводу происходящего на текущий момент, так как разработчики сами сказали, что ратуют за здоровую критику.

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

Поясню. На тот момент результатом был квадрат, с вращающимся вокруг него прямоугольником, управляемым мышкой, и wasd, перемещающие квадрат (игрока) по территории с фоном.
Читать дальше →

Подбор маски ввода по телефонному номеру

Время на прочтение7 мин
Охват и читатели179K
Данный плагин для jQuery позволяет автоматически подбирать подходящую маску ввода на основе введённого начала телефонного номера. Это позволяет сделать ввод номера телефона на странице web-cайта более быстрым и безошибочным. Кроме того, разработанный плагин может быть использован в других областях, если правила ввода возможно представить в виде нескольких масок ввода.
Читать дальше →

Попробуй БЭМ на вкус!

Время на прочтение11 мин
Охват и читатели69K
Эта статья рассказывает о том, как создать проект с использованием БЭМ-технологий.
Мы шаг за шагом создадим страничку каталога товаров, пользуясь принципами БЭМ в CSS, возможностями писать декларативный JavaScript на фреймворке i-bem.js и с использованием шаблонизатора BEMHTML. Помогать делать всё это будут bem tools, в частности — инструмент для разработки bem server.

Онлайн магазин

Важно: в статье нет особенных подробностей, её цель — получить проект максимально быстро. Текст, раскрывающий больше информации, пройдёт следующим постом.
Читать дальше →

Вебсокеты: боевое применение

Время на прочтение6 мин
Охват и читатели80K
imageВебсокеты — это прогрессивный стандарт полнодуплексной (двусторонней) связи с сервером по TCP-соединению, совместимый с HTTP. Он позволяет организовывать живой обмен сообщениями между браузером и веб-сервером в реальном времени, причем совершенно иным способом, нежели привычная схема «запрос URL — ответ». Когда два года назад я присматривался к этому стандарту, он был еще в зачаточном состоянии. Существовал лишь неутвержденный набросок черновика и экспериментальная поддержка некоторыми браузерами и веб-серверами, причем в Файрфоксе он был по умолчанию отключен из-за проблем с безопасностью. Однако теперь ситуация изменилась. Стандарт приобрел несколько ревизий (в том числе без обратной совместимости), получил статус RFC (6455) и избавился от детских болезней. Во всех современных браузерах, включая IE10, заявлена поддержка одной из версий протокола, и есть вполне готовые к промышленному использованию веб-серверы.

Я решил, что настало время попробовать это на живом проекте. И теперь делюсь, что из этого вышло.
Что вышло

Closure Platform. Костыли для Google Closure Library

Время на прочтение17 мин
Охват и читатели13K
Наша компания занимается разработкой собственного веб приложения. То есть без внешнего финансирования :) В этом есть как плюсы, так и минусы. Но то, что мне всегда нравилось и нравится, — это возможность попробовать что-то новое — технологии, подходы и решения. По некоторым причинам я не могу назвать сайт проекта, но могу поделиться тем опытом, который получил за время работы.
Так как я отвечаю за ту часть проекта, которая непосредственно видна пользователю, и с которой он вплотную работает, моя история и будет о ней).

Для начала, что бы читатель понимал о чём идёт речь, я хотел бы рассказать что у нас на «тёмной» стороне. А там Java, MySQL, Neo4J, Jetty, RabbitMQ и в конце этого длинного питона находиться nginx.

GCL


В конце 2010 года, мы, нашим «доблестным» отделом web-js, решили отказаться от старого шаблонизатора по ряду причин о которых ниже и перейти на что-то новое и действительно отвечающее реалиям нашего безумного проекта. Дело было в том, что в это время уже была реализована концепция виджетов и мест (place). Виджеты в нашем понимании — это некие независимые визуальные куски, которые общаются посредством каналов. По каналам можно передавать сообщения и подписываться на определённые типы сообщений. Виджет же, в свою очередь, не знает, где он находится в ДОМе — за это отвечают места (place). Большая проблема была в том, что виджет определял некие шаблоны, по которым он визуализировал данные. Мы можем использовать один и тот же виджет в разных местах, но выводить данные по-разному, следовательно, и пользователь мог взаимодействовать с данными по-разному. Но вернёмся к нашему древнему шаблонизатору. В то время все шаблоны подгружались и кешировались на клиенте в web-storage из-за чего была некая асинхронность в js коде — после создания виджета проходило какое-то время прежде чем можно было выводить данные. Мы хотели найти новое решение, которое бы убрало многие проблемы нашего шаблонизатора, например:
  • не было циклов
  • сложность локализации (в текстах нельзя было вставлять переменные)
  • не было условий и ветвления.

Мы проанализировали существующие на тот момент решения и выбрали Google Closure Library(GCL)… Да, я еще тогда не знал что Google даёт технологию, но не даёт инструментов по её использованию :)
К тому моменту проект насчитывал:
  • ~ 500 js файлов
  • ~ 30 css файлов
  • ~ 300 шаблонов.

Ответ кроется в комплексном подходе, предлагаемым Closure. Мы хотели, чтобы:
js код сжимался, оптимизировался в продвинутом режиме
  • удаление “мёртвого” js кода
  • css сжимались и валидировались
  • шаблоны проверялись, сжимались и хранились на стороне клиента.
  • лёгкий перевод ресурсов на разные языки

Все решения, которые были в сети на тот момент, давали что-то одно, гугл давал три связанных решения: Closure Compiler, Closure Template, Closure Stylesheets, которые работают как отдельно, так и вместе. И, когда они работают все вместе, то результат просто потрясающий!

Изменяем js код

Первое, с чего мы начали, — это проставили повсюду js зависимости… goog.require… Это было долго, заняло порядка 1 месяца. В результате, у нас упростилось подключение новых js файлов и логики — достаточно просто прописать зависимость и система автоматически подгрузит нужный код.
Гугл не даёт инструментария для использования своих технологий, но в самом гугле он есть, так как разработчики напрямую (через Г+) сообщили, что пишут в Эклипсе и у них полная поддержка Closure в нём.
Мы написали свой скрипт для Eclipse в виде Build Event, который при каждом сохранении js обновлял файл зависимостей deps.js для Closure. В то время практика была такая, что весь проект целиком (Tomcat, mysql, mq broker и т.д.) поднимался на машине у каждого разработчика, что отжирало 6гиг памяти и требовало около полутора-двух минут на старт всего проекта, так что мы тихо мигрировали на локальное проксирование js,css,img файлов через nginx, что значительно ускорило разработку. А то ждать пока эклипс пнёт томкат, чтобы тот начал обновлять файлы, было очень утомительно.

Переход с CSS на GSS

GSS чем-то похож на LESS, со своими особенностями.
Параллельно мы перешли с css на gss. Много проблем доставили всякие нестандартные атрибуты, а так в принципе достаточно просто переименовать css в gss. Единственное рекомендую сразу прошерстить свои css и внедрить mixin. Еще оставалась проблема с тем, что надо было как-то отслеживать какие файлы gss изменились и вызывать для них компилятор gss->css

Миграция на SOY

Что из себя представляют SOY. Это шаблоны, написаные на html похожем синтаксисе, и компилируемые в js код. Это решает важную проблему с кэшированием на стороне клиента всех шаблонов.
Одновременно со всеми этими нововведениями мы переводили старые шаблоны на SOY (Closure Templates). SOY оказался просто сказкой для программистов, так как мы смогли полностью отделить визуальную часть от логики и легко интегрировать ее в js код, потому как компилятор проставляет зависимости(goog.require). Так как в SOY есть пространство имён, то мы сразу продумали то, что у нас namespace будет отражаться в файловой системе в виде папок — как в java.
Большая проблема заключается во времени компиляции всех файлов — это слишком долго, на Core i7 3770K компиляция всех gss и soy занимает 20 секунд. Поэтому мы сделали скрипт который отслеживает изменённые gss и soy и компилирует только их — Гугл почему то не предоставляет такие инструменты в открытом доступе.
Обновление: В процессе написания статьи, была внедрена оптимизация и время компиляции(в режиме отладки) составляет сейчас 8-9 секунд.

Объединение

После решения этих проблем перед нами стояла последняя задача — заставить все эти три технологии работать вместе, чтобы ускорить работу сайта, ну и получить то, ради чего всё задумывалось.
Но тут выплыли некоторые нюансы: чтобы работало сжатие css селекторов нужно всюду в js использовать конструкцию goog.getCssName('display1') вместо прямого обращения 'display1'. То есть $element.addClasss('display1') нам нужно было заменить на конструкцию $element.addClasss(goog.getCssName('display1')). Кроме того, внутри goog.getCssName(...) нельзя использовать переменные и большое количество селекторов. То есть goog.getCssName('display'+value) не прокатит:), как не прокатит и goog.getCssName('display1 clearfix'). Это доставило много неудобств, из-за которых пришлось переписывать скрипты компиляции — чтобы они поддерживали возможность не сжимаемых css селекторов, так как весь старый код невозможно было сразу конвертнуть из вида «display-»+value во что-то нормальное. В самих SOY надо тоже по-особому выделять классы и идентификаторы которые будут сжиматься, {css display1} и т.д. На первом этапе у верстальщика был полный ад… Мы искали решение с подсветкой синтаксиса, в итоге мы нашли для Eclipse плагин который решил кучу проблем. (http://www.normalesup.org/~simonet/soft/ow/eclipse-closure-templates.en.html).
Что он умеет:
  • Подсветка и проверка синтаксиса SOY
  • Проверка на правильный вызов вложенных шаблонов. Пропущенные и лишние параметры
  • Быстрая навигация по шаблонам, через клавишу Ctrl

В общем, этот плагин стал для верстальщика манной небесной. SOY — развязывает вам руки, но и повышает ответственность. Чуть позже мы написали свои плагины для soy компилятора чтобы добавить нужные нам методы, наподобие конвертации строки в число и округление. На этом злоключения с SOY только начались. Дальше мы перевели серверные шаблоны на новый шаблонизатор. Для этого пришлось писать снова свои классы для поддержки тем и переводов. Для автоматической конвертации старых шаблонов в новый вид мы написали конвертер…
С переводами SOY на разные языки отдельная песня, гугл говорит: «там всё отлично». Там всё и вправду отлично, если есть инструменты:), а так вы можете генерить из soy файлов xlf файлы или файл. И вот тут оказалось, что никак нельзя взять старые переведённые xlf и просто добавить туда те, что не переведены… Это просто кошмар! Есть какой-то ужасный набор утилит для работы с этим форматом, но там нет того, что надо, у каждой фразы есть свой id, но он генерируется так изощренно, что даже сам класс генератор в Google Closure называется Fingerprint… Снова мы писали инструменты, которые позволили решить эту проблему.
Так же нам пришлось вынести из всех jsp страниц js код в отдельные модули, так как надо было готовиться к сжатию…

Последний бастион

Так прошло еще 7 месяцев с начала нашего пути, у нас были все нужные инструменты, все нужные связи между тремя технологиями, но сжатие в продвинутом режиме не работало:) Снова возникли проблемы, связанные с тем, что jQuery и многие плагины некорректно собираются в продвинутом режиме, необходимо было писать и подключать externs. С jQuery и плагинами разобрались, теперь выяснилось что вызовы js в SOY тоже надо заменить на некие несжимаемые вызовы. Я понимаю, что GC не рекомендует использовать прямые вызовы в onclick, и это легко сделать, когда вы пишите проект с 0 на GC, но, когда у вас тонна старого кода, это совсем не так просто, поэтому мы создали файл export.js, в котором прописали прокси для внешних вызовов вот в таком виде:
global_export["showLoginDialog"] = function(event, elem) {
    //... вызов окна логина.
};

Мы установили стандарт для всех таких экспортированных вызовов, вида function(event,this,...), то есть два первых параметра обязательно такие, а дальше какие угодно.
Решив эту проблему с экспортом (количество вызовов оказалось не более 20-30) оказалось, что всплыл еще один печальный факт с GCC(Google Closure Compiler). GCC сжимает в продвинутом режиме всё, что не «приколочено» кавычками ' или ", а, следовательно, вызовы внешних плагинов нужно было исправлять. Но самое большое разочарование заключалось в том, что клиент-серверное взаимодействие у нас работало на чётко документированном API, а после сжатия оно рушилось. Это снова откинуло нас на неопределённый срок…
Тут надо сделать отступление, сам Гугл передаёт не JSON-объекты, а массивы. Мы сначала думали, что это ProtoBuf — попробовали и оказалось, что нет, они просто ассоциируют каждый индекс массива с конкретным полем. Видимо, когда приходят данные с сервера, они их скармливают какому-то MessageFactory, который на основании мета-данных(тут возможны мета данные ProtoBuf для конкретного типа сообщений) связывает элементы с объектом. Если поступать как делает гугл, то, конечно, после сжатия и оптимизации никаких проблем нет и даже скорость повысится, так как с массивами работать быстрее).
Почему мы не поступили как гугл? Причина в том, что у нас много старого кода, который нам было необходимо поддерживать, но мы обязательно займёмся этой задачей, так как именно этот путь правильный.
Поиски решения привели к тому, что GCC мог отдавать карту преобразования имён, вида «старое поле объекта»:«новое название поля». Мы начали переделывать серверный код так, чтобы он мог поддерживать эту возможность, для этого был введён класс в общую для 5 сервисов библиотеку.
Вот такого вида:
public interface Constants {
    public static final String typeId = "typeId";
    public static final String user_id = "user_id";
    public static final String items = "items";
....
}

Перед сборкой специальная утилита брала map, которую сгенерировала GCC, и правила этот класс. Но, когда мы уже думали, что всё готово, оказалось, что в силу некоторых причин некоторая часть исторических данных необходимых на клиентской стороне хранится в виде json в базе и пока нет возможности сделать по-человечески… Даже изменив название полей, в базе нереально всё изменить, а так как при каждом изменении js кода генерируется новый map, конвертировать нет шанса. Это было полное фиаско… И тут пришла идея сделать наоборот — ведь GCC не только может отдавать map, но и принимать map преобразования. Мы взяли класс Constants, сконвертировали в map, скормили его GCC, тот сжал весь код, но не тронул названия полей, связанные с Client-Server API. Всё было хорошо, пока не обнаружились странные ошибки, связанные с некоторыми полями. Например, поле «items» должно было остаться «items» в выходном файле, а оно переименовывалось в «items1». Сложность была в том, что определить зависимость было сложно, так как на простых примерах всё работало как часы. Пришлось брать исходники GCC и запускать их под отладкой, оказалось, что если в коде вы где-либо упоминаете название свойства в кавычках (" или ') "<property_name>", то компилятор переименовывает вашу переменную даже если в map было указано «items:items». Создав баг в трекере GCC и добавив однострочную заплатку в комментарии, мы пересобрали свой GCC и удачно сжали весь проект.

Source map

Дальше мы прикрутили source map для того, чтобы разобраться в этой куче сжатых и оптимизированных-непонятных a.b.Fs(… Для этого пришлось тоже написать свою утилиту, потому что GCC почему-то не умеет добавлять в конец сжатого модуля
//@ sourceMappingURL= ...
, ну либо мы уже настолько выбились из сил на пути к цели, что пропустили в документации (скудной) этот пункт.

Итог

Что же мы получили в качестве результата:
В несжатом виде 1.6 МБ js код + 1.4 МБ шаблоны ~ 3.0 МБ
38 модулей в обычном режиме сжатия весят 2830 Кбайт в zip 445Кб
38 модулей в продвинутом режиме сжатия 1175 Кбайт в zip 266Кб
Сайт реально стал быстрее работать, пусть мы и потратили на это 12 месяцев. Параллельно мы решали задачи по работе и потихоньку шли к цели…

Вся эта история написана для того, чтобы вы могли себе представить стоят ли все эти телодвижения результата. Если бы мы начали проект сейчас на GC Library, у нас было бы меньше проблем, но если у вас уже есть тонна старого кода, то этот процесс может затянуться.
И заставьте верстальщика писать документацию по SOY, чтобы он вписывал туда примеры и типовые решения, это поможет ему быстрее адаптироваться и разобраться.(Со слов нашего верстальщика:) )
П.С.: Если кому интересно то мы ведём всю документацию в Google Docs, а баги в JIRA.

Инструментарий


Почему мы открываем полный стек инструментария для работы с GCL?
Ну сами технологии Open Source, но без костылей-инструментов они вообще никому не сдались. А я знаю есть много прекрасных сайтов где бы данные решения помогли. Ну и вообще я просто хочу сделать интернет чуть-чуть лучше:)
Итак, что вам нужно что бы развернуть Closure Platform. Это тестовый проект и базовая точка для начала разработки и для показа возможностей GCL.
OS: Linux OS, на худой конец OS X (BSD). Всё семейство Windows(мне вас только жаль:) ) идёт побоку из-за отсутствия нормального shell.
Java 1.6 и выше, ant, bash/sh и питон.
Большинство скриптов написано на bash, часть на java.
Почему не питон? Потому что он мне не нравится:)
Итак начнём.

Быстрый старт

git clone github.com/DisDis/ClosurePlatform.git
cd ClosurePlatform
ant
Запускаем в браузере WebUI/index.html

Структура проекта

Теперь более подробно.
Структура проекта CP:
  • src — тут должны хранится java исходники, в примере только Constants.java
  • themes — темы, там хранятся gss, soy и локали.
    • gss — стили
      • 0-definitions.gss — определения
      • *.gss — стили
      • allowed.cfg — разрешённые параметры
      • allowed_prop.cfg — разрешённые свойства
      • fixed.cfg — названия которые не сжимаются
      • .timestamp — это временный файл который хранит время последней удачной компиляции gss
    • locales — переводы в xlf
      • *.xlf — переводы
      • empty.xlf.template — шаблон для пустой локализации
    • templates — шаблоны
      • (namespace) — путь до шаблонов
      • global.properties — глобальные константы шаблонов
      • .timestamp — это временный файл, который хранит время последней удачной компиляции soy
  • tools — инструментарий
  • WebUI — то, что пойдёт на web-сервере в качестве root (если вы java разработчик, то вам это знакомо)
    • js — код
    • themes — откомпилированные данные тем
      • css
      • js — откомпилированные шаблоны
      • img, data — данные для темы, картинки и всё остальное.
    • *.html — станички
  • build.soy.xml — это задачи для анта что бы упростить запуск инструментария.


Настройка

В папке tools есть файл config.properties
Для чего он нужен:
TIMESTAMP_FNAME=".timestamp"
DEFINITION_GSS="0-definitions.gss"
THEMES_PATH=$DIR/../themes
THEME_LOCALES="en,ru"
LOCALE_SOURCE="en"
WEB_ROOT_PATH=$DIR/../WebUI
WEB_THEMES_PATH=$WEB_ROOT_PATH/themes
TOOL_LOCALE_PATH=$DIR/cl-templates/extractor
TOOL_MERGE_PATH=$DIR/merge-xlf
#SOURCE MAP config
SOURCE_MAP_ROOT=http://sourcemap.cp.com
SOURCE_MAP_FULLPATH=$SOURCE_MAP_ROOT/js/module/__THEME__/__LOCALE__/
MODULE_PATH=$WEB_ROOT_PATH/js/module


$DIR — это папка скрипта, который использует данные настройки
Параметер DEFINITION_GSS отвечает за gss, в котором будут размещены определения.
THEMES_PATH — путь до папки с темами (не откомпилированные gss и soy)
THEME_LOCALES — список поддерживаемых локализаций
LOCALE_SOURCE — в какой локале написаны тексты в soy
WEB_THEMES_PATH — папка куда будут складываться откомпилированные gss и soy
SOURCE_MAP_ROOT — путь до исходников, его легко потом завернуть через nginx куда надо.
SOURCE_MAP_FULLPATH — ну а это полный путь до конкретных не сжатых файлов
MODULE_PATH — путь до модулей
Все остальные параметры не так важны.

Eclipse или другая IDE

Установите плагин для SOY. Мы используем плагин для Eclipse.
В SOY файлах отлично работает ZenConding.
Добавьте событие на изменение файлов и вызывайте по нему ant soy_update

Локализация

Сначала делают локализацию.
Тут есть два пути, на начальной стадии можно просто воспользоваться пустым шаблоном empty.xlf.template, скопировав и переименовав в соответствующие локали. Например: en.xlf, только нужно поменять внутри параметр target-language на нужный.
Но когда вы будете готовы к тому что бы переводить тексты в soy, запустите create.translate.sh
Что делает данный инструмент — он сканирует все темы, в каждой тебе берёт все soy и делает из них xlf файл, далее он берёт старый файл xlf и переводы, для которых desc совпадает, переносит в новый файл, элементы, для которых не удалось найти совпадения по desc, заносятся в файл потерянных переводов .lost.xlf. Их надо либо руками перенести в нужное место, либо удалить, если переводы уже не нужны.
Да вот такой костыль. Если вы сможете предложить более простой метод, то мы с радостью упростим этот шаг. Он довольно редкий, так что тут есть место для оптимизации.
Под Mac OS, правда, этот пункт работать не будет:)

Компиляция GSS и SOY

За поиск изменённых gss и soy и дальнейшую компиляцию этих файлов отвечает скрипт compile.templates.sh. Его вы будете запускать очень часто, ну или автоматически через IDE. Скрипт работает в двух режимах, отладка и релиз.

Debug

Что он делает? Сканирует все темы на предмет файлов, которые изменились относительно времени изменения файла .timestamp и добавляет их в список на компиляцию.
Для каждого файла gss создаётся аналогичный файл css, имена не сжимаются. Для soy аналогично.

Release

Что бы запустить в релиз режиме надо просто указать параметр RELEASE при старте скрипта: compile.templates.sh RELEASE
В этом случае все(независимо изменялись они или нет) gss скомпилируются в один compact.css, все имена сжимаются. Все SOY компилируются в отдельные файлы с жатыми именами селекторов.

Константы

Как уже писалось, есть случаи, при которых нельзя чтобы некоторые свойства объекта сжимались, например, Client-Server взаимодействие. Вы можете поступить как гугл, но я не видел таких решений, чтобы кто-то другой поступал как гугл, ведь только у них есть полный стек для использования GCL.
В проекте-примере я генерирую map несжимаемых свойств из java файла который берётся из src/com/example/utils/Constants.java
За генерацию отвечает скрипт constantsToMap.sh, который берёт файл Constants.java и по нему создаёт файл property.in.map.
Проверяя при этом чтобы название констант совпадало с содержимым (items = «items»).
property.in.map это файл в котором
<старое значение>:<новое значение>

В нашем случае старое и новое значение одинаковое. В стандартной поставке GCC некорректно обрабатывает константы, есть баг в трекере и патч.
В тестовом проекте находится пропатченная версия GCC, я не знаю когда заплатку примут в основную ветку, но сообщество может ускорить это ;)
Вы можете сгенерировать этот файл откуда угодно, просто для примера приведено решение для java, формат данных простой.

Extern

Для взаимодействия с внешним кодом, например, jQuery или плагинами, которые не будут сжиматься, нужно прописывать Extern которые подключатся в разделе “сборка модулей”.
Хранятся все extern файл в папке tools/cl-externs
В примере есть tools/cl-externs/example.js для проекта, более подробно можно узнать из оф. документации GCC.

Сборка модулей

За это отвечает папка tools/gcmodule и приложение gcmodule.jar, его проще запускать через ant soy.create.modules
Перед запуском надо собрать все gss и soy в релизном режиме. Это можно сделать через ant soy.compile-RELEASE
Чтобы упростить задачу и сделать эти два действия одной командой
ant check.modules
В модули можно объединять несколько файлов или даже папок. Модуль может зависеть от других модулей и т.д. Лучше выделить общие части вашего сайта в отдельный модуль, а для всех страниц сделать отдельные модули. Почему следует поступит именно так, будет описано ниже.
Для конфигурации модулей есть файл config.cfg
Итак, почему это не скрипт, вначале я хотел написать его на bash, но это оказалось очень сложно, из-за сортировки массивов, поэтому java.
Суть работы программы — она берёт из config.cfg список папок и файлов, генерирует через гугловый инструмент дерево зависимостей, потом сортирует его по модулям и дальше отдаёт компилятору. Это сделано для обычного режима сжатия, в продвинутом режиме компилятор может сам построить зависимости, но для проектов, которые не сразу начинают с GCL, это будет нереально. Поэтому, для переходной фазы вашего проекта вы будете использовать обычное сжатие, а там нужно чётко скармливать файлы в нужной последовательности. О том, как переключить в обычный режим сжатия будет написано в ниже.
Тут надо заметить одну вещь — за один запуск можно сгенерировать только одну локаль для одной темы, к сожалению, побороть это непросто. Но можно запускать с различными параметрами и решить эту проблему.
Итак, в тестовом проекте после запуска сборки модулей в папке WebUI/js/module/ru/* будут валяться наши модули и сгенерированные и обработанные(если запускать через ant) source map для каждого файла.
На выходе так же будет файл property.out.map — это файл, содержащий карту переименований полей:
<оригинальное название поля>:<новое название>

config.cfg

Итак, файл настройки представляет из себя обычный JSON объект.
{
	options:<настройки>,
	modules:[<модуль>]
}

Что из себя представляют настройки:
{
		defines:{
/*Раздел с параметрами, их можно переопределять через командную строку и использовать в путях и названиях*/
			"LANG":"ru",/* язык компиляции */
			"THEME":"default",/*Тема*/
			"OPTIMIZATIONS": /* Режим оптимизации */
			/*"SIMPLE_OPTIMIZATIONS"*/
			"ADVANCED_OPTIMIZATIONS"
		},
		deps:{
			/* Настройка построителя зависимостей */
			params:" -o list",
			workPath:"../../tools/closure/bin",
			exec:"python ./calcdeps.py"
		},
		compiler:{
			/* Параметры компиляции */
			params:" 
Читать дальше →

Псевдо 3D или параллакс средствами javascript

Время на прочтение3 мин
Охват и читатели18K
Прочитав пост о псевдо 3D эффекте, стало интересно реализовать некий аналог для использования в веб приложениях. За результатом прошу под кат
Читать дальше →

TinyMCE 3.x: Подсчет количества слов и символов при редактировании контента

Время на прочтение2 мин
Охват и читатели6K
При использовании WYSIWYG редактора TinyMCE 3.x часто возникает потребность отображения статистики редактируемой статьи в реальном времени: отображение количества слов, символов и символов с пробелами.

Для чего это может требоваться?
Самое частое применение: создатели контента (копирайтеры, рерайтеры, контент-редакторы и т.д.) должны иметь возможность оценивать выполненный объем своей работы.

Плагин «из коробки» просто не работает для русского языка (не говоря о парсинге HTML-тегов). Поэтому было принято решение написания своего «велосипеда».
Что-нить получилось?

Производительность браузеров под Android. Часть 1: Вычисления на чистом JavaScript

Время на прочтение2 мин
Охват и читатели5.8K
Здравствуйте хабраюзеры. Сейчас пытаюсь написать игру на html5 + PhoneGap, конечно производительность не очень радует. Вот решил протестировать все браузеры доступные под Android в том числе и PhoneGap на предмет производительности, в этом цикле статьей будет рассмотрено:

1. Вычисления на чистом JavaScript.
2. Рендеринг с помощью DOM.
3. Рендеринг с помощью Canvas.
4. Рендеринг с помощью WebGL.
Читать дальше →

Навигация без перезагрузки используя expressjs, jade и History.js

Время на прочтение5 мин
Охват и читатели20K
Мне ранее не доводилось использовать в своей работе такую возможность HTML5 как History API. И вот настал тот час, разобраться в этом и провести небольшой эксперимент. Результатом этого эксперимента я решил поделиться с Вами.

И так что мы хотим:
— Навигация по сайту с использованием history api
— Получения данных с сервера в виде json объекта с последующим рендером на клиенте
— При прямом переходе рендер должен происходить на сервере
— Что бы все было легко и просто
Читать дальше →

Ближайшие события

Простая техника Parallax Scrolling

Время на прочтение2 мин
Охват и читатели126K
Доброго времени суток уважаемые хабраюзеры. На сегодняшний день Parallax Scrolling является неким трендом и я хочу рассказать о простой реализации данного эффекта. Техника основана на скорости изменения свойства background-position. Эффект Parallax Scrolling заключается в том, что фон движется медленнее чем содержимое

HTML разметка


Создаем два блока с атрибутами "data-type" и "data-speed":
<section id="home" data-type="background" data-speed="10" class="pages">
         <article>Простая техника Parallax Scrolling</article>
</section>
<section id="about" data-type="background" data-speed="10" class="pages">
         <article>Простая техника Parallax Scrolling</article>
</section>

Для управления значениями скорости и позиции в JavaScript, data-type используются как ключевые атрибуты при передачи необходимых параметров.

Читать дальше →

Пользовательские кнопки в API Яндекс.Карт 2.0

Время на прочтение10 мин
Охват и читатели26K
В API Яндекс.Карт 2.0 есть набор стандартных элементов управления картой:



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

Для того чтобы создать собственный макет элемента управления, нужно разобраться в части архитектуры API. В данной статье проводится краткий обзор понятий, с которыми должен ознакомиться разработчик перед выполнением этой задачи и объясняется общий принцип взаимодействия логической и визуальной части элементов управления. Также рассматриваются три примера по созданию макетов – от простого к сложному.

Статья рассчитана на разработчиков, которые уже имели опыт работы с API Яндекс.Карт 2.0. Для знакомства с основными концепциями рекомендую прочитать руководство разработчика.
Читать дальше →

3D-шахматы на HTML / CSS3 / JS

Время на прочтение1 мин
Охват и читатели37K


Французский разработчик Julian Garnier представил реализацию шахмат в 3D с использованием HTML/CSS3/JS, причем вся 3D-анимация выполнена с помощью CSS3.
Читать дальше →

Кнопка «цитировать» для iOs

Время на прочтение1 мин
Охват и читатели2.3K
При общении на форуме удобно иметь возможность цитировать в своем ответе фразы собеседников.
Простой скрипт поможет перенести выделенный кусок текста в поле ответа.

<a href="javascript://" onClick="document.getElementById('message').value = window.getSelection().toString();">цитировать</a>

демо

Для iOS

В мобильном Safari такое выделение не работает — сброс выделения текста происходит чуть раньше события нажатия на «цитировать».

Необходимо хранить выделение и регулярно обновлять данные:
Читать дальше →

Создаём сложный лабиринт в фоне веб-страницы (на клиенте)

Время на прочтение2 мин
Охват и читатели17K
Мне показалось немного странным, желание автора этого поста, генерировать изображения на сервере, в то время как современные браузеры позволяют делать это на клиенте. Поэтому хочу предложить другой, а точнее даже два других способа генерации фона.
Читать дальше →

Централизованная обработка исключений в Node.JS. Часть 2

Время на прочтение2 мин
Охват и читатели5.4K


Четыре месяца назад я писал о том, как можно удобно ловить исключения в node.js, в том числе и асинхронные, то есть те, которые брошены кодом, который вызван event loop'ом. В той статье я использовал модуль control-block для борьбы с ними, так как стандартный блок try-catch не справлялся.

Как оказалось, примерно в то же время Adam Crabtree выпустил стабильную версию похожего на control-block модуля под названием trycatch.
Читать дальше →

Вышел AWS SDK для Node.js

Время на прочтение1 мин
Охват и читатели7.5K
Вернер Фогель, CTO Amazon на прошедшей конференции re:Invent заявил, что использует Node.js для своих повседневных задач. А 4 декабря вышел официльный AWS SDK для Node.js. Теперь нет необходимости в использовании сторонних библиотек, опасаясь за их стабильность, и пытаться понять их документацию.
Читать дальше →