Подключение gulp для сжатия ассетов в Yii2
Я обожаю Yii2 - он очень прост и логичен, при этом очень гибок, мощно документирован и имеет невероятное количество плагинов, а также отзывчивое и гигантское комьюнити. Но порой, от некоторых вещей, которые реализованы в нем, впадаешь в ступор.
В качестве примера - сжатие и объединение ресурсов. Фреймворк предлагает достаточно подробную документацию, описывая сам механизм построения ассетов и настройку бандлов для сжатия и минификации. В принципе, этого достаточно. Но сами инструменты для сжатия достаточно кривые. Очень здорово, что фреймворк позволяет расширить эту функциональность. И очень классным решением будет подключить Gulp.js
Заводится он достаточно просто. В первую очередь, нужно вызвать консольную команду yii asset, чтобы сгенерировать конфиг для продакшена. Конфиг удобнее назвать assets_generate_conf.php и рядом же создать assets-dev.php, для возможности подключения не сжатых ассетов для разработки.
В assets_generate_conf указываем новые компрессоры вместо дефолтных:
'jsCompressor' => './tools/gulp compress-js --gulpfile tools/gulpfile.js --src {from} --dist {to}',
'cssCompressor' => './tools/gulp compress-css --gulpfile tools/gulpfile.js --src {from} --dist {to}',
Далее стандартно по мануалу. Если используются кастомные библиотеки для Bootstrap и Jquery, то их переопределенные версии также можно включить в итоговый бандл, указав параметр bundles:
// Asset manager configuration:
'assetManager' => [
'basePath' => '@webroot/assets',
'baseUrl' => '@web/assets',
'bundles' => [
'yii\bootstrap\BootstrapAsset' => [
//'sourcePath' => '@vendor/bower/bootstrap/dist',
'css' => []
],
'yii\bootstrap\BootstrapPluginAsset' => [
'css' => []
],
'yii\web\JqueryAsset' => [
'js' => []
]
]
],
Содержимое assets_generate_conf:
// In the console environment, some path aliases may not exist. Please define these:
Yii::setAlias('@webroot', __DIR__ . '/../web');
Yii::setAlias('@web', '/');
return [
'jsCompressor' => './tools/gulp compress-js --gulpfile tools/gulpfile.js --src {from} --dist {to}',
'cssCompressor' => './tools/gulp compress-css --gulpfile tools/gulpfile.js --src {from} --dist {to}',
// The list of asset bundles to compress:
'bundles' => [
'yii\web\YiiAsset',
'yii\web\JqueryAsset',
'yii\bootstrap\BootstrapAsset',
'yii\bootstrap\BootstrapPluginAsset',
'app\assets\AppAsset',
],
// Asset bundle for compression output:
'targets' => [
'all' => [
'class' => 'yii\web\AssetBundle',
'basePath' => '@webroot/assets',
'baseUrl' => '@web/assets',
'js' => 'js/all-{hash}.js',
'css' => 'css/all-{hash}.css',
'jsOptions' => [
'position' => \yii\web\View::POS_END
],
],
],
// Asset manager configuration:
'assetManager' => [
'basePath' => '@webroot/assets',
'baseUrl' => '@web/assets',
'bundles' => [
'yii\bootstrap\BootstrapAsset' => [
'css' => []
],
'yii\bootstrap\BootstrapPluginAsset' => [
'css' => []
],
'yii\web\JqueryAsset' => [
'js' => []
]
]
],
];
Далее, в корне создаем папку tools, в ней размещаем gulpfile.js со следующим содержимым:
var gulp = require('gulp');
var uglify = require('gulp-uglify');
var minifyJs = require('gulp-minify');
var cssMin = require('gulp-css');
// Need because of `yii console`
var rename = require('gulp-rename');
var minimist = require('minimist');
var options = minimist(process.argv.slice(2), { string: 'src', string: 'dist' });
var destDir = options.dist.substring(0, options.dist.lastIndexOf("/"));
var destFile = options.dist.replace(/^.*[\\\/]/, '');
// Use `compress-js` task for JavaScript files
gulp.task('compress-js', function() {
gulp.src(options.src)
.pipe(uglify())
.pipe(minifyJs())
.pipe(rename(destFile))
.pipe(gulp.dest(destDir))
});
// Use `compress-css` task for CSS files
gulp.task('compress-css', function() {
gulp.src(options.src)
.pipe(cssMin())
.pipe(rename(destFile))
.pipe(gulp.dest(destDir))
});
Через npm устанавливаем сам gulp локально - для меня это оказалось проще, чем таскать весь стек nodejs по серверам. Для того, чтобы gulp смог выполниться, в папке tools необходимо создать симлинк на непосредственно исполняемый файл:
ln -sfn node_modules/gulp/bin/gulp.js gulp
После установки gulp и всех подключаемых модулей, можно выполнить команду сборки:
php yii asset config/asset_generate_conf.php config/assets-prod.php
Если все пройдет успешно, то директории web появятся папки js и css, в которых будут минифицированные бандлы. Новый конфиг будет сгенерирован в config/assets-prod.php
После переключения приложения в продакшен режим, ассеты автоматически подключатся из минифицированных версий