JavaScript
20 July 2011

Dojo Build System, собственный опыт создания сборки

From Sandbox
Dojo — не самый популярный JavaScript фреймворк, несмотря на все свою мощь и положительные качества. Информация, которую я хочу донести сегодня до читателя, требуется для абсолютно каждого проекта, построенного с использованием этой технологии.

А поговорим мы о системе сборки.

Что это и зачем это нужно

Сообщество предлагает нам уже готовый оптимизированный релиз, предназначенный для размещения на сервере и использования в веб-приложениях. Подключая необходимые модули через 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=


В файловой системе это выглядит так:
директория dojoroot

Как видите, сборку я проводил из исходников, директория «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

+15
4.2k 28
Comments 20
Top of the day