Введение

Google Closure Compiler - уникальный инструмент, разработанный Google для сжатия и обфускации собственного javascript.

У него есть ряд интересных особенностей, которые отличают его от прочих упаковщиков.

Вместе с этим, инструмент это достаточно сложный. Основные его фичи скрываются в продвинутом режиме сжатия, для применения которого нужны соответствующие навыки и стиль программирования.

Google Closure Compiler написан на языке Java, причем так, что его достаточно просто расширить - конечно, если вам знакомы понятия компилятора, синтаксического дерева и понятен Java.

Официальная документация находится на http://code.google.com/intl/ru/closure/compiler/docs/overview.html.

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

В этом введении мы разберем основные опции компилятора и осуществим компиляцию простых примеров.

Первый запуск

Существует 3 способа запуска компилятора:

  1. Через веб-интерфейс. То есть, зайти на страничку, ввести или загрузить код и скомпилировать его с нужными опциями. Результат появится в текстовом поле.

    Этот способ удобен, чтобы поиграться с оптимизациями, понять от чего чего бывает, не более.

    Документация по этому способу: http://code.google.com/intl/ru/closure/compiler/docs/gettingstarted_ui.html.

  2. Через веб-сервис. Этот способ подразумевает отправку POST-запроса на адрес http://closure-compiler.appspot.com/compile. В параметрах запроса описаны флаги компиляции и передан код.
    Ответом будет сжатый javascript, либо ошибки компиляции.
    Этот способ удобен тем, что на веб-сервис google выкладывает, как правило, последнее стабильное API. Это убирает необходимость в хранении и обновлении компилятора.
    Документация по этому способу находится на http://code.google.com/intl/ru/closure/compiler/docs/gettingstarted_ui.html.
  3. Через приложение. Google Closure Compiler является приложением, написанным на языке java, и распространяется как в виде jar-файла, так и в виде исходных кодов SVN: http://closure-compiler.googlecode.com/svn.

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

Hello World

Сделаем небольшое упражнение по сжатию javascript-файла при помощи приложения Google Closure Compiler.
Для него вам понадобится Java Runtime Environment версии 6.

Этот пример содержит основные шаги для сжатия с использованием Google Closure Compiler.

  1. Создайте директорию с названием closure-compiler.
    Скачайте файл компилятора compiler.jar и сохраните его в директории closure-compiler.
  2. Создайте javascript-файл hello.js:
    /* простая функция */
    function hello(longName) {
        alert('Hello, ' + longName);
    }
    hello('New User');
    

    Сохраните его в директории closure-compiler.

  3. Скомпилируйте javascript-файл. Для этого запустите из директории closure-compiler следующую команду:

    java -jar compiler.jar --js hello.js --js_output_file hello-compiled.js
    

    Она сгенерирует новый файл hello-compiled.js, который содержит следующий код:

    function hello(a){alert("Hello, "+a)}hello("New User");
    

    Заметьте, что компилятор удалил комментарии, пробелы и лишнюю точку с запятой. Кроме того, он заменил параметр longName на более короткое имя a. В результате получили намного меньший javascript-файл.

    Чтобы убедиться, что получившийся файл работает корректно, подключите hello-compiled.js в HTML наподобие следующего:

    <html>
      <head><title>Hello World</title></head>
       <body>
         <script src="hello-compiled.js"></script>
      </body>
    </html>
    

    Загрузите этот HTML-файл в браузер и вы должны увидеть дружеский привет!

Основные флаги компилятора

Полный список флагов будет выведен при запуске:

java -jar compiler.jar --help

Он довольно длинный и, поначалу, большинство опций будут непонятны.
В этом разделе мы разберем самые основные опции сжатия, которые позволят сразу же делать основные операции по оптимизации javascript.

--js
Входной javascript-файл. Этот флаг может повторяться много раз с разными файлами:

--js script1.js --js script2.js ...

В результате получится объединенный сжатый файл.

Все флаги, которые допускают многократное использование, объявляются именно так. То есть, аргументы идут не через запятую, не через точку с запятой, а именно так: много раз один и тот же флаг.

--js_output_file
Имя файла для результата сжатия. По умолчанию: выводит в стандартный поток вывода.
--check_types
Включает проверку типов компилятором. По умолчанию - выключена. В любом случае, компилятор проверит синтаксическую правильность кода и выдаст ошибку в случае лишних скобок, незакрытых комментариев и т.п.

Более подробно о проверке типов вы можете прочитать в статье Объявление и проверка типов в примерах

--compilation_level
Уровень оптимизации, один из: WHITESPACE_ONLY, SIMPLE_OPTIMIZATIONS, ADVANCED_OPTIMIZATIONS. По умолчанию: SIMPLE_OPTIMIZATIONS.
Этот уровень подразумевает безопасные оптимизации и работает сходным образом с ShrinkSafe и YUI Compressor.
WHITESPACE_ONLY - простейший уровень для вырезания комментариев, пробелов и проверки кода на корректность.

Основные оптимизации раскрыты в статьях Оптимизации стандартного режима и Продвинутые оптимизации.

--formatting
Определяет форматирование выходного файла. Для печати сжатого файла в более-менее понятном виде, с форматированием и отступами, используйте значение --formatting PRETTY_PRINT.

Чем Google Closure Compiler отличается от (моего любимого) компрессора XXX ?

Чтобы ответить на этот вопрос, необходимо перечислить основные способы сжатия javascript. Их всего несколько:

  1. Удаление комментариев, лишних пробелов и прочего мусора через регулярные выражения.
    Этот способ использовался в первых компрессорах, таких как JSMin и packer. Позволяет сжать код за счет очистки от заведомо лишних вещей.
  2. Архивация типа недо-gzip.
    Из обычного файла можно сделать исполняемый самораспаковывающийся архив. Аналогично можно поступить с javascript. На этом основан известный упаковщик packer от Dean Edwards. При использовании этого способа код сжимается простеньким алгоритмом компрессии (сжатие со словарем), а то что получится - оборачивается в разархивирующий eval.

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

    Кроме того, на браузер ложится дополнительная нагрузка по разархивации полученного javascript.

  3. Сжатие, основанное на структуре кода и сокращении символов.
    Этот способ - самый последний. Его используют компрессоры ShrinkSafe, YUI Compressor и Google Closure Compiler.

    При сжатии этим методом оптимизатор сначала читает javascript в синтаксическое дерево. Затем он проходит по полученному дереву, заменяет локальные переменные на более короткие и производит оптимизации. Потом по оптимизированному дереву оптимизатор генерирует код, уже с оптимизациями.

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

Google Closure Compiler, как и другие оптимизаторы последнего поколения, не использует регекспов и не производит архивацию (да, с этим прекрасно справляется серверный gzip).

В чем же отличия Google Closure Compiler от других аналогичных оптимизаторов, таких как ShrinkSafe и YUI Compressor?

Отличие кроется в подходе к оптимизации.

В то время как YUI Compressor использует локальные оптимизации, то Google Closure Compiler использует комплексный анализ кода.

Он выполняет гораздо больше оптимизаций, чем и обусловлен лучший результат.

Кроме того, у Google Closure Compiler есть продвинутые оптимизации, аналога которым в других оптимизаторах нет. Есть там и расширенная проверка типов и множество других интересных возможностей, за более подробным описанием которых вы можете обратиться к другим статьям этого раздела.

YUI Compressor работает безопаснее и стабильнее для некоторых видов синтаксических конструкций (eval/with/CC, см. подробнее в статье Оптимизации стандартного режима), но если понимать, что происходит, то и Google Closure Compiler может быть не менее безопасен.

На момент написания статьи, Google не опубликовала утилит для сжатия CSS, а вот YUI Compressor это умеет. Так что выбрасывать его пока рановато.
Но вот для сжатия javascript лучше Google Closure Compiler найти что-либо сложно. Во всяком случае, в открытом доступе

Своя сборка компилятора

Для сборки компилятора подойдет практически любая ОС, т.к. используются только кросс-платформенные инструменты.

Чтобы собрать компилятор самостоятельно, его исходный код можно получить из SVN. Если у вас установлен стандартный SVN-клиент, то для этого подойдет команда:

svn co http://closure-compiler.googlecode.com/svn/trunk compiler

Последняя версия компилятора будет сохранена в директорию compiler.

Чтобы собрать компилятор, вам понадобится JDK версии 6 и установленный ANT.

Установка ANT довольно проста и описана в статье Installing Ant.

Для запуска достаточно запустить ant в директории с файлом сборки build.xml. После этого готовый к использованию jar-файл будет лежать в директории build.

Дополнительно

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