Было время, когда управление активами означало немного больше, чем вставка <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
.
Фильтр применяется к коллекции, чтобы изменить ее каким-либо образом. Если вы вернетесь к идее этапов в процессе управления активами, вы можете думать о том, что каждый этап реализуется одним или несколькими фильтрами. Так, например, один фильтр может отвечать за компиляцию, а другой — за минификацию.
Различные фильтры обычно применяются к разным коллекциям. Например, у вас может быть проект со следующим:
- Коллекция файлов .less, которые компилируются с помощью фильтра Less, минимизируются с использованием фильтра минимизации CSS и объединяются в один файл CSS.
- Коллекция
.css
файлов, которые просто уменьшаются - Коллекция файлов 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
.