Dojo — не самый популярный JavaScript фреймворк, несмотря на все свою мощь и положительные качества. Информация, которую я хочу донести сегодня до читателя, требуется для абсолютно каждого проекта, построенного с использованием этой технологии.
А поговорим мы о системе сборки.
Сообщество предлагает нам уже готовый оптимизированный релиз, предназначенный для размещения на сервере и использования в веб-приложениях. Подключая необходимые модули через dojo.require() мы инициируем синхронные HTTP GET запросы для получения необходимых ресурсов. Так как браузер ожидает завершения каждого вызова, то время загрузки страницы серьезно увеличивается. Оптимизировать подключение ресурсов нам помогут так называемые “layers” (далее просто — слои).
Задачи использования dojo build system для создания собственной сборки:
Слой на этапе подготовки сборки представляет собой конфигурационный файл, который включает в себя нужные нам подключения. Например, создадим основной слой, который будет подключаться на всех страницах веб-проекта, назовем его commonlayer.js.
ourcompany.shadow – допустим, это наш собственный модуль, кастомизация тени dojo.fx.shadow, которую мы хотим использовать.
И для сравнения дополнительный слой по работе с редактором dijit.Editor:
Мы меняли плагин вставки ссылки LinkDialog под собственные нужды. Выносим его из стандартной сборки и обзываем по-своему, как в случае с тенью. Смена названия происходит просто: исходный js код плагина добавляется строчка с новым объявлением, например:
где название ourcompany.dijit.… также говорит о физическом размещении модуля в файловой системе, \ourcompany\dijit\_editor\plugins\LinkDialog.js
В профиле layers.profile.js описываются необходимые слои и области именования, в объекте dependencies:
Такой файл создаст только оптимизированные 2 слоя, остальные файлы просто скопируются при сборки без изменений. Но их мы можем взять из официального релиза. Возможно у кого-то будет желание дополнить профиль так, чтобы он создавал полную сборку dojo, я не стал.
В src-версии dojo есть особенная папочка util, в которой можно найти скрипты сборки и утилиту shrinksafe для обфускации (оптимизирования) кода. Но не обольщайтесь, «из коробки» это не работает. Пришлось вникать и побеждать. Dojo предлагает два варианта сборки, для Windows через build.bat и для linux через build.sh. Сборку я проводил на родном компьютере, в окнах.
Непосредственно процесс сборки запускает файл \util\buildscripts\build.bat. Отредактируем его, указав правильный -classpath:
где rhino — java-движок, о котором я говорил выше.
Запустить сборку, указав параметры, удобно через makeRelease.bat файл. Я сделал это так, но я не специалист в написании батников, думаю у вас выйдет изящнее:
В файловой системе это выглядит так:
Как видите, сборку я проводил из исходников, директория «dojo-release-1.6.0-src», в которую подложил папку «ourcompany» с измененными модулями и ресурсами. Для запуска build.bat я использую следующие аргументы:
Полный список аргументов есть в документации.
После выполнения сборки директория приобретет вид:
В release лежит практически новогодний подарок — наша первая кастомная сборка dojo. В \release\ourcompany\ находятся два наших слоя, каждый из которых представляет собой оптимизированную могучую кучку из необходимых нам модулей для подключения.
Подключение слоев на страницу проекта:
Работа со слоями не исключает стандартной работы с модулями через dojo.require(). Необходимо отметить, что перед подключением dojo.require() проверяет, подключался ли уже такой модуль, и предотвращает повторное подключение.
Данная статья не только продукт глубоких умозаключений и творческого поиска, а реальный опыт, примененный в реальном веб-проекте. Что мы получили после создания и использования собственной сборки:
P.S. Внесение изменений в модули dojo часто несет за собой некоторые сложности с зависимостями. Например, при изменении плагина LinkDialog.js для dijit.Editor, который мы включили в сборку, потребовалось внести в src-версию папки ourcompany стандартные файлы ourcompany\dijit\nls\ru\common.js (loading.js). Без этой манипуляции слой editorlayer.js будет работать с ошибкой.
При изучении механизма создания сборок я использовал документацию на официальном сайте dojo toolkit:
http://dojotoolkit.org/reference-guide/build/
http://dojotoolkit.org/reference-guide/build/simpleExample.html
http://dojotoolkit.org/reference-guide/build/buildScript.html
А поговорим мы о системе сборки.
Что это и зачем это нужно
Сообщество предлагает нам уже готовый оптимизированный релиз, предназначенный для размещения на сервере и использования в веб-приложениях. Подключая необходимые модули через dojo.require() мы инициируем синхронные HTTP GET запросы для получения необходимых ресурсов. Так как браузер ожидает завершения каждого вызова, то время загрузки страницы серьезно увеличивается. Оптимизировать подключение ресурсов нам помогут так называемые “layers” (далее просто — слои).
Задачи использования dojo build system для создания собственной сборки:
- создание слоя используемых модулей. Все нужные модули соберутся в 1 файл, что заметно ускорит открытие страниц
- при необходимости изменений кода модулей dojo мы будем всегда работать только с исходным кодом (src-версий dojo)
- при наличии таких изменений действия по их встраиванию в очередные обновления сводятся к минимуму
Что необходимо для создания сборки
- Src-версия dojo, которую можно найти на странице загрузки
- JRE 1.5 и выше
- Опционально, собственные ресурсы (js, css и тд), которые мы хотим включить в сборку.
- Профиль (profile) – js файл, который описывает создание новой сборки.
- Движок Rhino от Mozilla Foundation. Dojo в свои утилиты для сборки его не подложил, хотя активно на него ссылается. Взять можно на сайте Mozilla
Создание слоев
Слой на этапе подготовки сборки представляет собой конфигурационный файл, который включает в себя нужные нам подключения. Например, создадим основной слой, который будет подключаться на всех страницах веб-проекта, назовем его commonlayer.js.
dojo.provide("ourcompany.commonlayer");
//основные модули
dojo.require("dojo.parser");
dojo.require("dojo.NodeList-fx");
dojo.require("dojo.data.ItemFileReadStore");
dojo.require("dojox.data.AndOrReadStore");
dojo.require("dojo.back");
dojo.require("dojox.fx._base");
dojo.require("dojo.cookie");
//специфический
dojo.require("ourcompany.shadow");
ourcompany.shadow – допустим, это наш собственный модуль, кастомизация тени dojo.fx.shadow, которую мы хотим использовать.
И для сравнения дополнительный слой по работе с редактором dijit.Editor:
dojo.provide("ourcompany.editorlayer");
//подключение самого редактора и плагинов
dojo.require("dijit.Editor");
dojo.require("dijit._editor.plugins.FontChoice");
dojo.require("dijit._editor.plugins.TextColor");
dojo.require("dijit._editor.plugins.EnterKeyHandling");
//специфический
dojo.require("ourcompany.dijit._editor.plugins.LinkDialog");
Мы меняли плагин вставки ссылки LinkDialog под собственные нужды. Выносим его из стандартной сборки и обзываем по-своему, как в случае с тенью. Смена названия происходит просто: исходный js код плагина добавляется строчка с новым объявлением, например:
dojo.provide("ourcompany.dijit._editor.plugins.LinkDialog");
где название ourcompany.dijit.… также говорит о физическом размещении модуля в файловой системе, \ourcompany\dijit\_editor\plugins\LinkDialog.js
Создание профиля
В профиле layers.profile.js описываются необходимые слои и области именования, в объекте dependencies:
dependencies = {
layers: [
//описание наших двух слоев
{
name: "../ourcompany/commonlayer.js",
resourceName: "ourcompany.commonlayer",
dependencies: [
"ourcompany.commonlayer"
]
},
{
name: "../ourcompany/editorlayer.js",
resourceName: "ourcompany.editorlayer",
dependencies: [
"ourcompany.editorlayer"
]
}
],
prefixes: [
//система знает, где искать папку /dojo, а остальные надо ей показать
//ourcompany - директория с нашими кастомизациями и ресурсами
[ "dijit", "../dijit" ],
[ "dojox", "../dojox" ],
[ "ourcompany", "../ourcompany" ]
]
}
Такой файл создаст только оптимизированные 2 слоя, остальные файлы просто скопируются при сборки без изменений. Но их мы можем взять из официального релиза. Возможно у кого-то будет желание дополнить профиль так, чтобы он создавал полную сборку dojo, я не стал.
Собираем
В src-версии dojo есть особенная папочка util, в которой можно найти скрипты сборки и утилиту shrinksafe для обфускации (оптимизирования) кода. Но не обольщайтесь, «из коробки» это не работает. Пришлось вникать и побеждать. Dojo предлагает два варианта сборки, для Windows через build.bat и для linux через build.sh. Сборку я проводил на родном компьютере, в окнах.
Непосредственно процесс сборки запускает файл \util\buildscripts\build.bat. Отредактируем его, указав правильный -classpath:
java -classpath "../rhino/js.jar;../shrinksafe/js.jar;../shrinksafe/shrinksafe.jar" org.mozilla.javascript.tools.shell.Main build.js %*
pause
где rhino — java-движок, о котором я говорил выше.
Запустить сборку, указав параметры, удобно через makeRelease.bat файл. Я сделал это так, но я не специалист в написании батников, думаю у вас выйдет изящнее:
@echo off
E:
cd \js\dojoroot
set FLDR=E:\js\dojoroot
echo buid root directory: %FLDR%
cd %FLDR%\dojo-release-1.6.0-src\util\buildscripts
build.bat action=clean,release profileFile=%FLDR%\layers.profile.js version=ourcompany-1.6.0/2 releaseName=
В файловой системе это выглядит так:
Как видите, сборку я проводил из исходников, директория «dojo-release-1.6.0-src», в которую подложил папку «ourcompany» с измененными модулями и ресурсами. Для запуска build.bat я использую следующие аргументы:
- action — необходимые действия, clean — очистить старую директорию сборки, release — создать сборку
- profileFile — путь к профилю
- version — версия сборки, можно будет возвращать через dojo.version
- releaseName — у меня пустое, если его задать, в папке release появится поддиректория с вашим названием
Полный список аргументов есть в документации.
После выполнения сборки директория приобретет вид:
В release лежит практически новогодний подарок — наша первая кастомная сборка dojo. В \release\ourcompany\ находятся два наших слоя, каждый из которых представляет собой оптимизированную могучую кучку из необходимых нам модулей для подключения.
Подключение слоев на страницу проекта:
<!-- Как и раньше требуется подключение ядра dojo:-->
<script type="text/javascript" src="dojo/dojo.js"></script>
<!-- Затем подключается общий для всех страниц слой: -->
<script type="text/javascript" src="ourcompany/commonlayer.js"></script>
<!-- Для страниц, где используется редактор, подключаем: -->
<script type="text/javascript" src="ourcompany/editorlayer.js"></script>
Работа со слоями не исключает стандартной работы с модулями через dojo.require(). Необходимо отметить, что перед подключением dojo.require() проверяет, подключался ли уже такой модуль, и предотвращает повторное подключение.
Результат
Данная статья не только продукт глубоких умозаключений и творческого поиска, а реальный опыт, примененный в реальном веб-проекте. Что мы получили после создания и использования собственной сборки:
- существенно выросла скорость загрузки всех страниц. Время загрузки по личным наблюдениям в Firebug и тестам webpagetest.org сократилось примерно на секунду
- на главной странице проекта, где не используется редактор, 129 последовательных HTTP GET запросов превратились в один (sic!)
- проект пережил обновление с dojo 1.4 на версию 1.6, и теперь легко будет обновляться на каждую новую версию
P.S. Внесение изменений в модули dojo часто несет за собой некоторые сложности с зависимостями. Например, при изменении плагина LinkDialog.js для dijit.Editor, который мы включили в сборку, потребовалось внести в src-версию папки ourcompany стандартные файлы ourcompany\dijit\nls\ru\common.js (loading.js). Без этой манипуляции слой editorlayer.js будет работать с ошибкой.
При изучении механизма создания сборок я использовал документацию на официальном сайте dojo toolkit:
http://dojotoolkit.org/reference-guide/build/
http://dojotoolkit.org/reference-guide/build/simpleExample.html
http://dojotoolkit.org/reference-guide/build/buildScript.html