В предыдущей статье можно ознакомится как фреймворк работает со статикой, которая поставляется с компонентами, созданными специально для фреймворка.
В то же время есть огромное количество сторонних компонентов в виде Bower/NPM пакетов, работу с которыми фреймворк так же упрощает и с которыми отлично интегрируется.
Alameda
Для загрузки AMD модулей вместе с фреймворком поставляется Alameda. Фреймворк самостоятельно заботится о том, чтобы сгенерировать конфигурацию для Alameda таким образом, чтобы вы могли вызывать нужные модули просто используя имя модуля без полного пути.
AMD модули для модулей фреймворка
Простите за тавтологию, но звучит именно так. AMD модули могут использоваться в том числе в модулях фреймворка для того, чтобы не загружать ненужный код на страницах до того как он нужен.
Здесь происходят следующие операции:
- для всех модулей фреймворка с JavaScript файлами (проверяется наличие директории
modules/*/assets/js
) - создается алиас (опция
paths
конфигурации Alameda) для названия модуля и каждой функциональности, которую он предоставляет
Например, для модуля MyModule
с meta.json
:
{
"package" : "MyModule",
"category" : "modules",
...
"provide" : "my_feature",
...
}
Будут созданы два алиаса:
MyModule -> /modules/MyModule/assets/js
my_feature -> /modules/MyModule/assets/js
Если AMD модуль находится по пути modules/MyModule/assets/js/my_module.js
, то вызвать его можно будет, к примеру, как my_feature/my_module
. Достаточно удобно, если есть несколько альтернативных реализаций одного AMD модуля, в этом случае будет использоваться тот, который установлен.
AMD модули в Bower пакетах
Фреймворк сканирует при наличии содержимое директории bower_components
в корне сайта и генерирует Alameda конфигурацию для каждого найденного пакета (опция packages
конфигурации Alameda) следующего вида:
{
"name" : "jquery",
"main" : "dist/jquery",
"location" : "/bower_components/jquery"
}
Генерация именно пакетов позволяет поддерживать не только модули из одного файла как jQuery, но и более сложные конфигурации как lodash-amd
, где можно грузить не всю библиотеку, а лишь некоторые её части (более старые версии фреймворка умели генерировать только алиасы).
В качестве названия модуля выступает имя директории, таким образом jQuery можно использовать как jquery
.
Для того, чтобы понять какой файл использовать в ключе main
используется одноименный ключ из bower.json
(первый JavaScript файл в случае если указан массив файлов).
AMD модули в NPM пакетах
Аналогично bower_components
, фреймворк так же анализирует директорию node_modules
.
С анализом package.json
всё сложнее, поскольку многие пакеты ориентированы в первую очередь на использование в окружении Node.js.
Для того, чтобы найти подходящий файл для использования в окружении браузера фреймворк пробует следующие ключи в package.json
в порядке от более высокого приоритета к более низкому:
browser
jspm.main
main
В процессе использования иногда приходится делать PR для пакетов, которые пока этого не поддерживают (Redux, seamless-immutable).
Bower/NPM пакеты как зависимости модулей фреймворка
Для фреймворка существует необязательный модуль Composer assets
, который позволяет декларативно указывать Bower/NPM зависимости для модулей фреймворка в их meta.json
ключах require_bower
и require_npm
.
Эти зависимости будут установлены для соответствующего модуля автоматически, при это не нужен ни доступ к терминалу на сервере, ни установленного Node.js, а при условии наличия конфликтов установка модуля прервется, то есть интеграция получается полноценной.
Выглядит это следующим образом:
{
...
"require" : [
"System>=6.25",
"System<7.0",
"composer_assets"
],
"require_npm" : {
"qrcodejs" : {
"version" : "1.0.0",
"files" : [
"qrcode.js"
]
}
}
}
Во-первых необходимо указать зависимость от функциональности composer_assets
, посколько именно она добавляет поддержку нужных ключей, без этого фреймворк не понимает что такое require_npm
.
Во-вторых нужно указать какой модуль нужен и (опционально) какие файлы нужно подключать.
Дело в том, что по умолчанию фреймворк считает пакеты как содержащие AMD модули и генерирует для них конфигурации аналогичные вышеуказанным. Но иногда нужно подключить простой JavaScript файл, файл стилей или веб-компонент.
Если нужен только AMD модуль, то конфигурацию можно упростить до следующей:
{
...
"require_npm" : {
"jquery" : "^3.0.0"
}
}
Одним важным моментом интеграции является поддержка алиасов для установленных через Composer assets
пакетов по путях bower_components
и node_modules
. Иными словами jQuery из последнего сниппета можно достать по пути /node_modules/jquery/dist/jquery.js
, при том что физически файл находится по пути /storage/Composer/vendor/npm-assets/jquery/dist/jquery.js
.
Режим продакшена
Если включить кэширование и сжатие статики в настройках фреймворка, то файлы из {require_npm|require_bower}.*.files
пройдут ту же обработку, что и файлы поставляемые с модулями фреймворка, так что большинство поддерживаемых оптимизаций будет применяться и здесь.
Так же типичным для многих пакетов в "дикой природе" является сопровождение обычных собранных модулей их минифицированными версиями (в bower.json
и package.json
при этом указываются обычные). Таким образом в продакшене вместо dist/jquery.js
на самом деле будет загружен dist/jquery.min.js
.
Кастомная версия Alameda
Как это бывает, к сожалению, достаточно часто, фреймворк поставляется с кастомизированными сборками сторонних проектов, в данном случае с кастомной версией Alameda.
Проблема с оригиналом в том, что в "дикой природе" есть некоторые не совсем корректно сформированные модули, которые без патча Alameda поддерживать отказывается, кастомная же версия умеет загружать и такие модули что избавляет от ручной конфигурации, которая потребовалась бы в противном случае.
Пример такого некорректного, но теперь поддерживаемого фреймворком, модуля:
define('inline-styles-formatter',[], function () {
...
});
define('as-html-formatter',[], function () {
...
});
define('scribe-plugin-inline-styles-to-elements',[
'./inline-styles-formatter',
'./as-html-formatter'
], function (
inlineStylesFormatter,
asHtmlFormatter
) {
...
});
Обсуждение ситуации с разработчиком Alameda можно найти здесь, а форк с нужной функциональность здесь.
Напоследок
Как можно увидеть, фреймворк отлично интегрируется как с стандартным способом установки Bower/NPM пакетов, так и поддерживает их на уровне зависимостей модулей фреймворка.
Конфигурации AMD пакетов генерируются для подавляющего большинства правильно оформленных пакетов полностью автоматически.
Всегда рад новым идеям и конструктивным комментариям.
phpishka
Интересно бы было увидеть сравнение с более мейнстримоввми фреймворками, типо того как недавно тут было PHPixie против Laravel. Без холиворов а кратко и по сути. Вашы статьи интересны но киллер фич я пока не увидела.
nazarpc
В моих предыдущих статьях есть сравнение некоторых аспектов и существенные отличия в подходах по сравнению с другими мейнстримовыми фреймворками. Если кратко, то то, что в других фреймворках требует код и кучу централизованной конфигурации здесь либо работает совсем без конфигурации (используются вменяемые настройки по умолчанию, которые можно при необходимости переопределить) либо использует распределенную и чаще всего декларативную конфигурацию.
Для быстрого погружения можно посмотреть несколько скринкастов, больше записать пока руки не доходят: https://www.youtube.com/playlist?list=PLVUA3QJ02XIiKEzpD4dxoCENgzzJyNEnH
Скринкасты могут быть слегка устаревшими, но не смотря на это они всё равно полезны, просмотрев их вы оцените какой подход используется и сможете оценить, нравится ли вам такое или нет.