RequireJS Optimizer
- Требования
- Загрузка
- Пример настройки
- Основы
- Оптимизация одного файла JavaScript
- Поверхностные исключения для быстрого разработки
- empty: пути для ресурсов сети/CDN
- Оптимизация одного файла CSS
- Оптимизация всего проекта
- Оптимизация проекта с несколькими страницами
- Параметры Turbo
- Интеграция с has.js
- Карты исходных кодов
- Все параметры конфигурации
- Методы развертывания
- Распространённые ошибки
RequireJS имеет инструмент оптимизации, который выполняет следующие действия
- Объединяет связанные скрипты в слои построения и сжимает их с помощью UglifyJS (по умолчанию) или Closure Compiler (опция при использовании Java).
- Оптимизирует CSS, встраивая файлы CSS, на которые ссылаются @import, и удаляя комментарии.
Оптимизатор является частью адаптера r.js для Node и Nashorn и предназначен для запуска в рамках этапа сборки или упаковки после завершения разработки и готовности к развертыванию кода для пользователей.
Оптимизатор будет объединять только те модули, которые указаны в массивах строковых литералов, передаваемых в вызовы require и define на верхнем уровне, или в строковых литералах require('name') в упрощённой обёртке CommonJS. Поэтому он не найдёт модули, которые загружаются с помощью имени переменной:
var mods = someCondition ? ['a', 'b'] : ['c', 'd']; require(mods);
но 'a' и 'b' будут включены, если указаны так:
require(['a', 'b']);
или:
define(['a', 'b'], function (a, b) {}); Это поведение позволяет динамическую загрузку модулей даже после оптимизации. Вы всегда можете явно добавить модули, которые не были найдены статическим анализом оптимизатора, используя параметр include.
Требования
Оптимизатор можно запустить с помощью Node, Java с Rhino или Nashorn, или в браузере. Требования для каждого варианта:
- Node: (предпочтительно) Node 0.4.0 или более поздней версии.
- Java: Java 1.6 или более поздней версии.
- Браузер: начиная с версии 2.1.2, оптимизатор может работать в веб-браузере с дополнительными функциями массивов. Хотя параметры оптимизатора такие же, как показано ниже, он вызывается через JavaScript вместо параметров командной строки. Он также подходит только для создания оптимизированных отдельных файлов, а не для оптимизации каталога. См. пример в браузере. Этот вариант действительно полезен только для предоставления веб-базированных пользовательских сборок вашей библиотеки.
Для использования в командной строке Node является предпочтительной средой выполнения. Оптимизатор работает намного быстрее с Node.
Все примеры команд на этой странице предполагают использование Node и выполнение в командной строке Linux/OS X. См. README r.js, чтобы узнать, как запустить его в Java.
Загрузка
1) Вы можете загрузить инструмент на странице загрузки.
2) Если вы используете Node с NPM, вы можете установить r.js глобально как часть пакета "requirejs" в NPM:
> npm install -g requirejs > r.js -o app.build.js
Если вы используете Windows, вам может потребоваться ввести r.js.cmd вместо r.js. Или вы можете использовать DOSKEY:
DOSKEY r.js=r.js.cmd $*
Если вы хотите установить requirejs локально в проекте как пакет npm, а не глобально:
> npm install requirejs
При такой локальной установке оптимизатор можно запустить, выполнив r.js или r.js.cmd файл, расположенный в каталоге проекта node_modules/.bin.
При локальной установке вы также можете использовать оптимизатор через вызов функции внутри программы Node.
Остальная часть этой страницы предполагает, что r.js загружен вручную со страницы загрузки. Это обычно наиболее понятный и переносимый способ использования оптимизатора.
Пример настройки
Примеры на этой странице предполагают, что вы загрузили и сохранили r.js в каталоге, который является соседним с вашим проектом. Оптимизатор, который является частью r.js, может находиться в любом месте, но вам, вероятно, придётся соответствующим образом настроить пути в этих примерах.
Пример настройки:
- каталог приложения
- main.html
- css
- common.css
- main.css
- scripts
- require.js
- main.js
- one.js
- two.js
- three.js
- r.js (Оптимизатор r.js со страницы загрузки)
main.html имеет теги script для require.js и загружает main.js через вызов require, например:
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
<script data-main="scripts/main" src="scripts/require.js"></script>
</head>
<body>
<h1>My App</h1>
</body>
</html>
main.js загружает one.js, two.js и three.js через вызов require:
require(["one", "two", "three"], function (one, two, three) {
});
main.css содержит следующий контент:
@import url("common.css");
.app {
background: transparent url(../../img/app.png);
}
Основы
Аргументы командной строки взаимозаменяемы с свойствами профиля сборки
Вы можете указать параметры либо в командной строке:
node r.js -o baseUrl=. paths.jquery=some/other/jquery name=main out=main-built.js
или в профиле сборки. В файле build.js те же аргументы командной строки могут быть указаны следующим образом:
({
baseUrl: ".",
paths: {
jquery: "some/other/jquery"
},
name: "main",
out: "main-built.js"
})
затем просто передайте имя файла профиля сборки оптимизатору:
node r.js -o build.js
Аргументы командной строки имеют приоритет над настройками профиля сборки, и вы можете их комбинировать:
node r.js -o build.js optimize=none
Существует ограничение синтаксиса аргументов командной строки. Точки рассматриваются как разделители свойств объекта, чтобы разрешить что-то вроде paths.jquery=lib/jquery преобразоваться в следующее в оптимизаторе:
paths: {
jquery: 'lib/jquery'
}
но это означает, что вы не можете задать значение для свойства paths "core/jquery.tabs". Это не сработает: paths.core/jquery.tabs=empty:, так как это приведёт к неправильной структуре:
paths: {
'core/jquery': {
tabs: 'empty:'
}
}
Если вам нужно задать путь, подобный "core/jquery.tabs", используйте файл build.js с параметрами сборки, указанными в качестве объекта JavaScript, а не аргументов командной строки.
Список всех параметров см. в разделе все параметры конфигурации.
Правила разрешения относительных путей:
В общем случае, если это путь, он относительный к файлу build.js, используемому для хранения параметров сборки, или, если используются только аргументы командной строки, к текущей рабочей директории. Примеры свойств, которые являются путями к файлам: appDir, dir, mainConfigFile, out, wrap.startFile, wrap.endFile.
Для baseUrl он относительный к appDir. Если нет appDir, то baseUrl относительный к файлу build.js или, если используются только аргументы командной строки, к текущей рабочей директории.
Для paths и packages они относительны к baseUrl, как и в require.js.
Для свойств, которые являются идентификаторами модулей, они должны быть идентификаторами модулей, а не путями к файлам. Примеры: name, include, exclude, excludeShallow, deps.
Настройки конфигурации в главном JS-модуле, который загружается в браузере во время выполнения, по умолчанию не считываются оптимизатором
Это связано с тем, что настройки конфигурации сборки могут быть очень разными, с несколькими целевыми оптимизациями. Поэтому для оптимизатора требуется отдельный набор параметров конфигурации.
В версии 1.0.5+ оптимизатора параметр mainConfigFile можно использовать для указания расположения конфигурации во время выполнения. Если указать путь к вашему главному JS-файлу, первый requirejs({}), requirejs.config({}), require({}), or require.config({}) в этом файле будет разобран и использован в качестве параметров конфигурации, переданных оптимизатору:
mainConfigFile: 'path/to/main.js'
Приоритет конфигурации: командная строка, профиль сборки, mainConfigFile. Другими словами, конфигурация mainConfigFile имеет наименьший приоритет.
Оптимизация одного файла JavaScript
Используйте указанную выше настройку. Если вы хотели оптимизировать только main.js, вы можете использовать эту команду из каталога appdirectory/scripts:
node ../../r.js -o name=main out=main-built.js baseUrl=.
Это создаст файл appdirectory/scripts/main-built.js, который будет содержать содержимое main.js, one.js, two.js и three.js.
Обычно оптимизированные файлы не следует сохранять с исходными файлами проекта. Обычно их сохраняют в копии вашего проекта, но для упрощения примера они сохраняются вместе с исходными файлами. Измените параметр out= на любой каталог, который у вас есть, содержащий копию исходных файлов. Затем можно изменить имя файла main-built.js на просто main.js, чтобы страница HTML загружала оптимизированную версию файла.
Если вы хотите включить require.js вместе с исходным файлом main.js, вы можете использовать команду такого типа:
node ../../r.js -o baseUrl=. paths.requireLib=../../require name=main include=requireLib out=main-built.js
Поскольку "require" является зарезервированным именем зависимости, вы создаёте зависимость "requireLib" и сопоставляете её с файлом require.js.
После завершения оптимизации можно изменить тег script так, чтобы он ссылался на "main-built.js" вместо "require.js", и вашему оптимизированному проекту потребуется только один запрос к скрипту.
Если вы хотите обернуть свой скомпилированный файл, чтобы его можно было использовать на страницах без загрузчика AMD, например, RequireJS, см. FAQ по оптимизации.
Поверхностные исключения для быстрого развития
Вы можете использовать подход оптимизации одного файла JavaScript, чтобы ускорить процесс разработки. Оптимизируя все модули вашего проекта в один файл, за исключением модуля, над которым вы сейчас работаете, вы сможете быстро перезагружать проект в браузере, но при этом у вас сохранится возможность отладки модуля.
Это можно сделать, используя параметр excludeShallow. Используя пример настройки выше, предположим, что вы сейчас разрабатываете или отлаживаете two.js. Вы можете использовать эту команду оптимизации:
node ../../r.js -o name=main excludeShallow=two out=main-built.js baseUrl=.
Если вы не хотите минимизировать файл main-build.js, передайте optimize=none в команде выше.
Затем настройте HTML-страницу для загрузки файла main-built.js вместо main.js, настроив путь к "main" на "main-built":
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
<script src="scripts/require.js"></script>
<script>
require.config({
paths: {
//Comment out this line to go back to loading
//the non-optimized main.js source file.
"main": "main-built"
}
});
require(["main"]);
</script>
</head>
<body>
<h1>My App</h1>
</body>
</html>
Теперь, при загрузке этой страницы, require() для "main" загрузит файл main-built.js. Поскольку excludeShallow указало на исключение только файла two.js, two.js по-прежнему будет загружен как отдельный файл, позволяя вам видеть его как отдельный файл в отладчике браузера, чтобы вы могли устанавливать точки останова и лучше отслеживать его отдельные изменения.
empty: пути к ресурсам сети/CDN
У вас может быть скрипт, который вы хотите загрузить с сети доставки контента (CDN) или любого другого сервера на другом домене.
Оптимизатор не может загружать сетевые ресурсы, поэтому, если вы хотите, чтобы он был включён в сборку, убедитесь, что создали конфигурацию путей для сопоставления файла с именем модуля. Затем, для запуска оптимизатора, загрузите скрипт CDN и передайте оптимизатору конфигурацию путей, которая сопоставляет имя модуля с локальным путём к файлу.
Однако, скорее всего, вам не нужно включать этот ресурс в сборку. Если у скрипта нет зависимостей, или вы не хотите включать его зависимости или будете включать их другим способом, то вы можете использовать специальную схему 'empty:' в конфигурации путей, чтобы просто пропустить файл при оптимизации.
В вашем файле main.js создайте конфигурацию путей, которая даёт скрипту имя модуля. Это можно сделать, даже если скрипт не определяет модуль с помощью вызова define(). Конфигурации путей просто используются для сопоставления коротких идентификаторов модулей/скриптов с URL-адресом. Это позволяет использовать разные конфигурации путей для оптимизации. В main.js:
requirejs.config({
paths: {
'jquery': 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min'
}
});
require(['jquery'], function ($) {
});
Затем, при запуске оптимизатора, используйте 'empty:' для конфигурации путей:
node ../../r.js -o name=main out=main-built.js baseUrl=. paths.jquery=empty:
Или, в профиле сборки:
({
baseUrl: ".",
name: "main",
out: "main-built.js",
paths: {
jquery: "empty:"
}
})
Оптимизация одного файла CSS
Используйте вышеуказанную настройку, если вы хотите оптимизировать только main.css, вы можете использовать эту команду изнутри каталога appdirectory/css:
node ../../r.js -o cssIn=main.css out=main-built.css
Это создаст файл appdirectory/css/main-build.css, который будет содержать содержимое main.css, иметь правильно изменённые пути url() и удалённые комментарии.
Обратите внимание на примечания к оптимизации одного файла JavaScript об избегании сохранения оптимизированных файлов в вашем первозданном дереве исходников. Это делается только для упрощения примера.
Примечание: исправление пути url() всегда будет исправлять пути относительно пути параметра сборки cssIn, а не параметра сборки out.Оптимизация всего проекта
Оптимизатор может позаботиться об оптимизации всех файлов CSS и JS в вашем проекте, используя профиль сборки.
Создайте профиль сборки, назовите его app.build.js и поместите его в каталог scripts. Файл app.build.js может находиться где угодно, но просто убедитесь, что вы скорректировали пути в приведённом ниже примере — все пути будут относительными к расположению файла app.build.js. Пример app.build.js:
({
appDir: "../",
baseUrl: "scripts",
dir: "../../appdirectory-build",
modules: [
{
name: "main"
}
]
})
Этот профиль сборки сообщает RequireJS о копировании всего каталога appdirectory в каталог-сиблинг appdirectory-build и применении всех оптимизаций в каталоге appdirectory-build. Настоятельно рекомендуется использовать для вывода каталог, отличный от исходного каталога — в противном случае, скорее всего, произойдут неприятности, так как оптимизатор перезапишет ваши исходные данные.
RequireJS будет использовать baseUrl для разрешения путей для любых имён модулей. baseUrl должен быть относительным к appDir.
В массиве modules укажите имена модулей, которые вы хотите оптимизировать, в примере, "main". "main" будет сопоставлен с appdirectory/scripts/main.js в вашем проекте. Система сборки затем отследит зависимости для main.js и вставит их в файл appdirectory-build/scripts/main.js.
Она также оптимизирует любые файлы CSS, которые она найдёт внутри appdirectory-build.
Для запуска сборки выполните эту команду изнутри каталога appdirectory/scripts:
node ../../r.js -o app.build.js
После завершения сборки вы можете использовать appdirectory-build как ваш оптимизированный проект, готовый к развёртыванию.
Оптимизация проекта с несколькими страницами
requirejs/example-multipage — это пример проекта, имеющего несколько страниц, но разделяющего общую конфигурацию и общий оптимизированный уровень сборки.
Параметры Turbo
По умолчанию оптимизатор выполняет наиболее безопасные и надёжные действия, которые избегают сюрпризов после сборки. Однако, в зависимости от настройки вашего проекта, вы можете отключить некоторые из этих функций для получения более быстрых сборок:
- Самым большим потребителем времени является минификация. Если вы выполняете сборки в рамках рабочего процесса разработки, установите optimize в
"none". - Если выполняется оптимизация всего проекта, но нужно только сжать уровни сборки, указанные в параметрах modules, а не остальные файлы JS в каталоге вывода сборки, вы можете установить skipDirOptimize в
true. - Обычно каждый запуск оптимизации всего проекта удаляет каталог вывода сборки, указанный в параметре dir, для чистоты. Некоторые параметры сборки, такие как onBuildWrite, изменят каталог вывода таким образом, что дважды выполнять эту операцию над теми же файлами опасно. Однако, если вы выполняете простые сборки без дополнительных преобразований файлов, помимо минификации уровня сборки, вы можете установить keepBuildDir в
trueдля сохранения каталога сборки между запусками. Затем будут скопированы только файлы, изменившиеся между запусками сборки.
Начиная с версии 2.1.2, оптимизатор использует некоторые сокращения скорости по умолчанию, если optimize установлен на "none". Однако, если вы используете "none" для optimize и планируете сжать скомпилированные файлы после запуска оптимизатора, вы должны установить normalizeDirDefines в "all", чтобы вызовы define() были правильно нормализованы, чтобы противостоять сжатию. Если вы выполняете сжатие с помощью параметра optimize, вам не нужно беспокоиться об установке этого параметра.
Интеграция с has.js
has.js — это прекрасный инструмент, который добавляет удобную проверку наличия функций для вашего проекта. Поддерживается оптимизация путей кода для тестов has.js.
Если ваш код использует тесты, такие как:
if (has("someThing")) {
//use native someThing
} else {
//do some workaround
}
Вы можете определить объект has в конфигурации сборки с истинными или ложными значениями для некоторых тестов has(), и оптимизатор заменит тест has() истинным или ложным значением.
Если ваш профиль сборки выглядел так:
({
baseUrl: ".",
name: "hasTestModule",
out: "builds/hasTestModule.js",
has: {
someThing: true
}
})
Тогда оптимизатор преобразует пример кода выше в:
if (true) {
//use native someThing
} else {
//do some workaround
}
Затем, если вы используете значение оптимизации по умолчанию "uglify" в r.js 0.26.0 или более поздней версии, или если значение optimize установлено в "closure" (когда запуск под Java), минификатор оптимизирует ветвь мёртвого кода! Таким образом, вы можете выполнять кастомизированные сборки своего кода, оптимизированные для набора тестов has().
Карты исходных данных
В версии 2.1.6 и выше есть экспериментальная поддержка карт исходных данных. Она работает для сопоставления сжатого, свёрнутого кода с несжатыми, отдельными модулями и только тогда, когда optimize установлен в "uglify2". optimize, установленный в "closure" позволяет только сопоставлять сжатый, свёрнутый код с несжатым свёрнутым кодом (closure доступен только при запуске под Java с Rhino). Несжатые файлы будут отображаться в инструментах разработчика с расширением файла ".src.js".
Чтобы включить генерацию карты исходных данных, установите generateSourceMaps в true. Поскольку минификатор должен иметь полный контроль над сжатым файлом для генерации карты исходных данных, preserveLicenseComments должен быть явно установлен в false. Есть способ включить некоторые комментарии к лицензиям в сжатом исходном коде.
Оптимизатор поддерживает sourceURL (установив useSourceUrl в true), для отладки объединённых модулей как отдельных файлов. Однако, это работает только с несжатым кодом. Карты исходных данных преобразуют сжатый файл в несжатую версию. Использовать useSourceUrl с generateSourceMaps не имеет смысла, так как useSourceUrl требует значений исходного кода в виде строк, что запрещает полезную минификацию, выполненную в сочетании с generateSourceMaps.
Все параметры конфигурации
В каталоге requirejs/build находится файл example.build.js, содержащий подробности о всех разрешённых параметрах конфигурации оптимизатора.
Методы развёртывания
Оптимизатор r.js разработан, чтобы предложить некоторые примитивы, которые могут быть использованы для различных сценариев развёртывания путём добавления другого кода поверх него. Обратитесь к странице wiki по методам развёртывания для идей о том, как использовать оптимизатор таким образом.
Распространённые ошибки
Если у вас возникнут проблемы с примерами ниже, вот некоторые распространённые ошибки, которые могут быть источником проблемы:
Не указывайте каталог вывода в пределах области исходного кода вашего JavaScript
Например, если ваш baseUrl — 'js', а вывод сборки идёт в 'js/build', могут возникнуть проблемы с дополнительными вложенными файлами, генерируемыми при каждом запуске оптимизации. Это руководство относится только к оптимизациям, которые не являются оптимизациями одного файла.
Избегайте имён оптимизации, которые находятся вне baseUrl
Например, если ваш baseUrl — 'js', а ваши оптимизированные цели:
name: '../main'
оптимизация может перезаписать или поместить файлы за пределами каталога вывода. В таких случаях создайте конфигурацию paths для сопоставления этого файла с локальным именем, например:
paths: {
main: '../main'
}
затем используйте имя:
name: 'main'
в качестве цели оптимизации.
Обратите внимание на ограничения сборки конфигурации shim. В частности, вы не можете загружать зависимости для библиотеки shim с CDN. Для получения дополнительной информации см. раздел конфигурации shim.
© jQuery Foundation and other contributors
Licensed under the MIT License.
http://requirejs.org/docs/optimization.html