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


В то же время есть огромное количество сторонних компонентов в виде 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 пакетов генерируются для подавляющего большинства правильно оформленных пакетов полностью автоматически.


Всегда рад новым идеям и конструктивным комментариям.


» Репозиторий на GitHub

Поделиться с друзьями
-->

Комментарии (2)


  1. phpishka
    20.12.2016 01:55

    Интересно бы было увидеть сравнение с более мейнстримоввми фреймворками, типо того как недавно тут было PHPixie против Laravel. Без холиворов а кратко и по сути. Вашы статьи интересны но киллер фич я пока не увидела.


    1. nazarpc
      20.12.2016 02:01

      В моих предыдущих статьях есть сравнение некоторых аспектов и существенные отличия в подходах по сравнению с другими мейнстримовыми фреймворками. Если кратко, то то, что в других фреймворках требует код и кучу централизованной конфигурации здесь либо работает совсем без конфигурации (используются вменяемые настройки по умолчанию, которые можно при необходимости переопределить) либо использует распределенную и чаще всего декларативную конфигурацию.


      Для быстрого погружения можно посмотреть несколько скринкастов, больше записать пока руки не доходят: https://www.youtube.com/playlist?list=PLVUA3QJ02XIiKEzpD4dxoCENgzzJyNEnH
      Скринкасты могут быть слегка устаревшими, но не смотря на это они всё равно полезны, просмотрев их вы оцените какой подход используется и сможете оценить, нравится ли вам такое или нет.