Статьи

Начало работы с Assetic

Было время, когда управление активами означало немного больше, чем вставка <link> или двух и пары тегов <script> в ваш HTML.

В настоящее время, однако, такой подход просто не сработает. Во-первых, производительность. Активы значительно снижают производительность как с точки зрения размера файла, так и с точки зрения количества HTTP-запросов — их оптимизация стала неотъемлемой частью процесса разработки. Это усугубляется распространением мобильных устройств.

Кроме того, по мере того как клиентские приложения становятся все более и более сложными, управление зависимостями между скриптами и библиотеками становится все более сложным.

Кроме того, такие технологии, как Less, Compass и Coffeescript, требуют компиляции ресурсов, добавляя еще один шаг в процесс управления активами.

В этой статье я собираюсь посмотреть на пакет PHP под названием Assetic, который помогает управлять, компилировать и оптимизировать ресурсы, такие как скрипты, таблицы стилей и изображения.

Что такое управление активами?

Давайте начнем с того, что на самом деле означает управление активами.

В простейшем случае это способ управления ресурсами, которые требуются веб-сайту или веб-приложению — или конкретной странице — и их зависимостям. Это может включать в себя обеспечение доступности конкретной библиотеки для вашего JavaScript или обеспечение сброса CSS перед вашими другими стилями.

Иногда это помогает взглянуть на управление активами с точки зрения нескольких отдельных этапов. Первый — это компиляция, необходимый шаг, если вы используете CSS-фреймворк, такой как Less, SASS, SCSS, Stylus, Compass и т. Д., Или что-то вроде Coffeescript или Dart . Есть также несколько дополнительных шагов компиляции, связанных с некоторыми инструментами на основе JavaScript; например, компиляция шаблонов Handlebars, Twig или Mustache.

Следующий этап — оптимизация. Для CSS, как правило, вы минимизируете свои файлы таблиц стилей, когда переходите в рабочий режим. Для JavaScript вы, вероятно, уменьшите или упакуете свои исходные файлы. Изображения часто могут быть значительно уменьшены в размерах с использованием различных алгоритмов сжатия, а в некоторых случаях вы также можете уменьшить количество HTTP-запросов, кодируя их в BASE-64 и встраивая данные в таблицы стилей.

Наконец, конкатенация. Сокращение количества HTTP-запросов может значительно повысить производительность, поэтому файлы CSS и JavaScript часто объединяются в один большой файл для каждого типа. Техника построения «спрайтов» применяет тот же принцип к изображениям, хотя это выходит за рамки этой статьи.

Представляем Assetic

Assetic — это пакет PHP, предназначенный для помощи в процессе управления активами.

При начале работы с Assetic необходимо понять несколько важных понятий — коллекции и фильтры .

Коллекция объединяет кучу активов. Один файл является активом. «Пользователи Nix, в частности, будут знакомы с glob, который по сути является способом собрать кучу файлов, имена файлов которых соответствуют определенному шаблону; Assetic также рассматривает их как актив. Например, шаблон glob pattersm /assets/js/*.js ссылается на все файлы в /assets/js с расширением .js .

Фильтр применяется к коллекции, чтобы изменить ее каким-либо образом. Если вы вернетесь к идее этапов в процессе управления активами, вы можете думать о том, что каждый этап реализуется одним или несколькими фильтрами. Так, например, один фильтр может отвечать за компиляцию, а другой — за минификацию.

Различные фильтры обычно применяются к разным коллекциям. Например, у вас может быть проект со следующим:

  1. Коллекция файлов .less, которые компилируются с помощью фильтра Less, минимизируются с использованием фильтра минимизации CSS и объединяются в один файл CSS.
  2. Коллекция .css файлов, которые просто уменьшаются
  3. Коллекция файлов Coffeescript компилируется с использованием фильтра Coffeescript, минимизируется с помощью фильтра Google Closure Compiler, а затем объединяется в один файл .js .

Точные комбинации типов файлов и фильтров будут зависеть от того, какие технологии вы используете, и от ваших личных предпочтений, таких как предпочтительный минификатор.

Assetic обеспечивает поддержку многочисленных модулей, предоставляя вам гибкость выбора любого подхода, который вы предпочитаете. Например, вам решать, будете ли вы минимизировать свой JavaScript с помощью JSMin, YUI Compressor или Google Closure Compiler.

Установка Assetic

Вы можете установить Assetic, загрузив или клонировав с Github или, что еще лучше, через Composer:

 "kriswallsmith/assetic": "1.2.*@dev" 

В Packagist также доступны пакеты Assetic для таких сред, как Zend Framework , Symfony , Laravel и Silex .

использование

Давайте начнем с простого примера — создания коллекции активов для объединения нескольких файлов JavaScript:

 $js = new AssetCollection(array( new GlobAsset('/assets/js/libs/*'), new FileAsset('/assets/js/app.js'), )); print $js->dump(); 

Приведенный выше код берет все файлы .js из /assets/js/libs а затем файл /assets/js/app.js и объединяет их при /assets/js/app.js dump() — вскоре мы рассмотрим, что вы делаете с выводом ,

Вы можете расширить приведенный выше пример, добавив фильтр — в этом случае он использует JSMin для минимизации результирующего JavaScript:

 $scripts = new AssetCollection(array( new GlobAsset('/assets/js/libs/*'), new FileAsset('/assets/js/app.js'), ), array( new JSMinFilter(), )); print $scripts->dump(); 

Примечание. Если вы хотите использовать JSMin, вы можете использовать следующую реализацию PHP:
"lmammino/jsmin4assetic": "1.0.*@dev" (посмотреть его на Github можно здесь ).

Вашим таблицам стилей потребуется отдельная коллекция ресурсов, поскольку фильтры ведут себя по-разному. Предположим, у вас есть куча CSS-файлов, и вы используете Less для определения своей сетки:

 $styles = new AssetCollection(array( new FileAsset('/assets/less/grid.less', array(new LessFilter())), new GlobAsset('/assets/css/*'), ), array( new Yui\CssCompressorFilter('/path/to/yuicompressor.jar'), )); print $styles->dump(); 

Он использует LessFilter для компиляции grid.less , объединяет его вместе со всеми файлами .css в /assets/css , а затем сжимает все это с помощью YUI-компрессора .

Обратите внимание, что для того, чтобы приведенный выше пример работал, вам нужно убедиться, что у вас правильно установлен YUI Compressor, указан правильный путь к его файлам .jar , и добавьте в свой composer.json : "leafo/lessphp": "0.4.*@dev"

Если вы предпочитаете использовать CssMin, а не YUI Compressor, вам нужно установить его , и ваш код станет:

 $styles = new AssetCollection(array( new FileAsset('/assets/less/grid.less', array(new LessFilter())), new GlobAsset('/assets/css/*'), ), array( new CssMinFilter(), )); print $styles->dump(); 

Если вы используете SASS вместо Less, установите SCSSphp , добавив следующее в ваш composer.json :

 "leafo/scssphp": "dev-master" 

Затем вы можете использовать ScssphpFilter для компиляции ваших активов SASS.

Вы также можете оптимизировать изображения. В этом примере мы используем glob для извлечения всех файлов изображений из assets/img и сжатия их с помощью OptiPng , затем делаем то же самое с Jpegs, но используем Jpegoptim :

 $images = new AssetCollection(array( new GlobAsset('/assets/img/*.png', array(new OptiPngFilter())), new GlobAsset('/assets/img/*.jpg', array(new JpegoptimFilter()), )); 

Классы менеджера и AssetFactory

Есть и другие способы настройки ваших активов. Класс AssetManager по сути, является хранилищем активов с AssetManager — например, вы можете собрать коллекции активов, которые мы определили в предыдущем разделе, следующим образом:

 $am = new AssetManager(); $am->set('jquery', new FileAsset('/path/to/jquery.js')); $am->set('scripts', $scripts); $am->set('styles', $styles); 

Класс FilterManager работает примерно так же:

 $fm = new FilterManager(); $fm->set('sass', new SassFilter('/path/to/parser/sass')); $fm->set('yui_css', new Yui\CssCompressorFilter('/path/to/yuicompressor.jar')); 

Затем вы можете использовать класс AssetFactory для упрощения всего процесса:

 use Assetic\Factory\AssetFactory; $factory = new AssetFactory('/path/to/asset/directory/'); $factory->setAssetManager($am); $factory->setFilterManager($fm); $factory->setDebug(true); $styles = $factory->createAsset(array( '@reset', // load the asset manager's "reset" asset 'css/src/*.scss', // load every scss files from "/path/to/asset/directory/css/src/" ), array( 'scss', // filter through the filter manager's "scss" filter '?yui_css', // don't use this filter in debug mode )); echo $styles->dump(); 

Выход

Я показал, как выбрать то, что вы хотите включить и как применять фильтры; но я еще не посмотрел, где вы это делаете или как вы ссылаетесь на это. Есть несколько подходов, которые вы можете использовать.

Одна возможность — создать файл PHP в общедоступном каталоге, например, JavaScripts.php и ссылаться на него из своего HTML, как если бы он был активом:

 <script src="/assets/JavaScripts.php"></script> 

Или вы можете создать файл с именем stylesheets.php и встроить его в строку:

 <style> <?php include('/assets/stylesheets.php'); </style> 

В качестве альтернативы вы можете создавать файлы .css и .js и просто ссылаться на них как обычно. Вы можете использовать AssetWriter для этого:

 use Assetic\AssetWriter; $scripts.js = new AssetCollection(array( new GlobAsset('/assets/js/libs/*'), new FileAsset('/assets/js/app.js'), ), array( new JSMinFilter(), )); // Set target path, relative to the path passed to the // AssetWriter constructor as an argument shortly $scripts->setTargetPath('scripts.js'); $am->set('scripts.js', $scripts.js); // see above for instantiation of $styles $styles->setTargetPath('stylesheets.css'); $am->set('styles', $styles); $writer = new AssetWriter('/assets/build'); $writer->writeManagerAssets($am); 

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

Кэширование

Assetic поставляется с простым файловым механизмом кэширования, чтобы фильтры не запускались без необходимости. Вот пример кэширования выходных данных YUI Compressor:

 use Assetic\Asset\AssetCache; use Assetic\Asset\FileAsset; use Assetic\Cache\FilesystemCache; use Assetic\Filter\Yui; $yui = new Yui\JsCompressorFilter('/path/to/yuicompressor.jar'); $js = new AssetCache( new FileAsset('/path/to/some.js', array($yui)), new FilesystemCache('/path/to/cache') ); // the YUI compressor will only run on the first call $js->dump(); $js->dump(); $js->dump(); 

Резюме

В этой статье я представил Assetic — пакет PHP для управления активами. Я показал, как вы можете использовать его для управления зависимостями, запуска процессов компиляции, минимизации / упаковки / сжатия / оптимизации ресурсов и объединения файлов для минимизации количества HTTP-запросов. Обязательно ознакомьтесь с документацией для получения подробной информации обо всех доступных фильтрах; или вы можете даже взглянуть на реализацию FilterInterface / расширение BaseFilter с целью определения своего собственного. Для пакетов, которые дополняют его, обратитесь к предлагаемым пакетам либо при первой установке, либо suggests раздел suggests в его файле composer.json .