[MinifyX] Новые возможности старичка

Всем привет! Сегодня поговорим про дополнение MinifyX. Все знают, что это, но не все, что оно больше не поддерживается автором. Основная причина — ядро минифая (библиотека Munee) уже давно не обновляется. Вроде есть проблемы с Bootstrap 4.
Но мне он нравится. А главное, он выполняет всё, что требуется — собирает и минифицирует мои скрипты и стили без ошибок. Я не компилирую сасы, лесы, кофе. Единственное, не хватало разных мелочей для удобства. Вот захотелось мне собирать всё в один файл — и обычные скрипты и скрипты дополнений. Сниппетом это сделать не очень просто, но можно — для каждого шаблона делать отдельный вызов с перечнем необходимых файлов. Но этот вариант не вызвал у меня энтузиазма. И я решил реализовать другой подход. У меня сниппет MinifyX вызывается в чанке head, в котором я определяю секцию HEAD страницы. Поэтому я подумал, а почему бы не использовать подход загрузки файлов по требованию.

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

В общем, я сосредоточился на сниппете. Первое, что я добавил, это группы. Т.е. скрипты можно группировать и подключать указывая группы. Так стало гораздо удобнее. Вот как выглядят эти самые группы.
<?php

return [
    'baseCss' => [
        '[[+assets_url]]css/bootstrap.min.css',
	'[[+assets_url]]css/font-awesome.min.css',
	'[[+assets_url]]css/bootstrap-theme.css',
	'[[+assets_url]]components/sitestatistics/css/web/style.css',
        '[[+assets_url]]components/hybridauth/css/web/default.css'
    ],
    'ticketsCss' => [
        '{assets_url}components/tickets/css/web/default.css',
        '{assets_url}components/tickets/js/web/editor/editor.css'
    ],
    'ticketsJs' => [
        '{assets_url}components/tickets/js/web/default.js',
        '{assets_url}components/tickets/js/web/editor/jquery.markitup.js'
    ],
    'officeCss' => [
        '[[+assets_url]]components/office/css/main/default.css',
        '[[+assets_url]]components/office/css/profile/default.css'
    ],
    'officeJs' => [
        '[[+assets_url]]components/office/js/main/default.js',
        '[[+assets_url]]components/office/js/auth/default.js',
        '[[+assets_url]]components/office/js/profile/default.js'
    ],
];
Для групп используется отдельный файл core/components/minifyx/config/groups.php. Для подключения групп предназначено 2 параметра — cssGroups и jsGroups. Вот пример для раздела с тикетами:
{$_modx->runSnippet('MinifyX', [
        'cssGroups' => 'baseCss,ticketsJs',
        'jsGroups' => 'ticketsJs',
    ]
)}
Таким образом, выделяем в группу общие стили, которые нужны для всех страниц, а затем добавляем нужные группы для конкретного случая. Это реально удобно, так как можно управлять файлами в одном месте и не надо бегать по шаблонам, если нужно добавить или удалить файл из загрузки.

Но я выше уже говорил, что у меня только один вызов сниппета из чанка head для всех шаблонов. Поэтому я реализовал механизм хуков, позволяющий расширять функционал компонента. В них можно подгружать или заменять файлы в зависимости от условий. Работает это так
{$_modx->runSnippet('MinifyX', [
	'cssGroups' => 'baseCss',
	'preHooks' => 'main'  // main.php  - хук-файл
    ]
)}
Хуки — это сниппеты. Но так как я сторонник файловых элементов, то добавил возможность указывать файлы. Нужно просто указать имя файла, который должен лежать в папке core/components/minifyx/hooks/. Можно указывать несколько хуков через запятую. В сниппете и файле доступен объект $MinifyX, у которого есть методы для подключения как групп так и отдельных файлов.
Хуки бывают 2-х типов — хуки предварительной обработки и хуки пост обработки. Они указывают в параметрах «preHooks» и «hooks» соответственно. Сделал по аналогии с FormIt, чтобы не путаться. В пре-хуках можно добавлять группы и файлы. В пост-хуках изменять имя сформированного кэш-файла и его содержимое, что может пригодиться в случае ошибок минификации (компрессии).
Мой пре-хук для блога
<?php

if ($modx->resource->parent == 10) {
    // Добавляем группы
    $MinifyX->addCssGroup('ticketsCss,officeCss');
    $MinifyX->addJsGroup('ticketsJs,officeJs');
    // Добавляем файлы
    $MinifyX->addCssSource("{assets_url}css/jquery.fancybox.css");
    $MinifyX->addJsSource("{assets_url}js/jquery.fancybox.js");
}
// Стили сайта. Должны подключаться самыми последними
$MinifyX->addCssSource("{assets_url}css/style.css");
Условия можно определить разные. Можно, например, прописать ТВшку у ресурсов с флагом или с названием файла для подключения, можно проверять урл или id шаблона. В общем, придумать можно много примеров.
Методы addCssGroup, addJsGroup, addJsSource и addCssSource добавляют группы и файлы к уже добавленым. Методы setCssGroup, setJsGroup, setJsSource и setCssSource заменяют ранее добавленные файлы на указанные.

Пример пост-хука:
<?php
// Получаем и изменяем содержимое кэш-файла стилей
if ($MinifyX->isCss()) {
    $content = preg_replace('#vm ax#', 'vmax', $MinifyX->getContent());
    $MinifyX->setContent($content);
}
// Пример изменения названия файла скриптов. Имейте ввиду, что эти файлы при очистке кэша удаляться не будут.
if ($MinifyX->isJs()) {
    $MinifyX->setFilename('main.min.js');
}
Данный функционал уже вовсю работает на моем сайте. Проблем пока не выявлено. Если посмотреть на исходники страниц, то можно увидеть только по одному файлу стилей и скриптов у каждой страницы. Правда пришлось подкрутить Tickets и Office, так как в них нельзя отключить все скрипты. Для каждого набора файлов генериться свой файл. Поэтому их у меня около 20 в общей сложности. В результате скорость загрузки страницы немного повысилась — плюс в копилку оптимизации.

Итог

Так как Василий больше не поддерживает это дополнение, то и PR слать бессмысленно. Но он по доброте душевной решил отдать MinifyX в хорошие руки. На Гитхабе я уже могу хозяйничать, а вот добавлять в репозитории новые версии никак. Поэтому пока радуемся за меня. :) В дальнейшем чего-нибудь придумаем.
Сергей Шлоков
18 января 2018, 18:46
8
1 976
+12

Комментарии: 58

Василий Наумкин
18 января 2018, 22:10
+5
На Гитхабе я уже могу хозяйничать, а вот добавлять в репозитории новые версии никак.
Передал права и в магазине — на здоровье.
    Сергей Шлоков
    18 января 2018, 22:20
    +1
    Вот и придумали :)

    П.С. По Tickets и Office. С тикетс можно PR послать (возможность отключать файлы редактора markItUp). А вот с Office такой возможности нет. Если коротко о проблеме — если отключить загрузку скриптов, то перестает инициализироваться переменная OfficeConfig. Думаю, инициализацию javascript конфига нужно вынести из условия проверки наличия файла скриптов.
Taras
19 января 2018, 00:43
+2
хорошо было бы MinifyX css непортил
#id {height: 10vmax; }
возвращает:
#id {height:10vm ax}
из-за пробела неработает
    Сергей Шлоков
    19 января 2018, 10:02
    +1
    В текущей версии можно в хуке сделать замену «vm ax» на «vmax» через preg_replace например. Пока только так. Будет больше времени и желание, гляну как подсунуть другую библиотеку для обработки css.
      Юрий Эффа
      19 января 2018, 14:28
      0
      Пожалуйста, подскажите где посмотреть как сделать хук для Minifyx… Актуальная тема для vmin\vmax
Sem
Sem
19 января 2018, 09:01
+2
Однозначно, крутое обновление, но — ядро минифая (библиотека Munee) портит весь кайф.
Вот если бы за минификацию css отвечал инструмент — github.com/css/csso
То оптимизация стилей стала бы просто сказкой на MODX, так как ещё не было случая когда эта библиотека что-то не могла правильно обработать в CSS, да и обновляется она регулярно.
А так, Сергей, как всегда, спасибо Вам за Ваши старания.
    Сергей Шлоков
    19 января 2018, 10:10
    +1
    Спасибо!

    Насколько я понял, csso — яваскрипт компрессор. Это не вариант.

    Munee сам не работает с файлами напрямую. Он использует зависимости — для less, sass, coffeescript, javascript и т.д. А они практически все периодически обновляются. Вот например пакет для работы с css.
    В принципе, никто не мешает форкнуть Munee и прикрутить другие зависимости.
Aleksandr Huz
19 января 2018, 12:01
0
Тогда я тоже поделюсь своим вариантом. Мне тоже нравится MinifyX, но сторонние библиотеки я подключаю отдельно. Надоело подключать их вручную, поэтому переместил все в MinifyX.

Добавил параметр
'modules' => 'jquery,lazysizes,magnific,sweetalert,slick'
а в сниппете:
$modules = $modx->getOption('modules', $scriptProperties, '', true);

$arr_modules = explode(',',$modules);
foreach ($arr_modules as $value){
    
    $moduleCss = $value . 'Css';
    $pathCss = $modx->getOption($moduleCss, $scriptProperties, '', true);
    if( $pathCss != '' ){
        $link = '<link rel="preload" href="'.$pathCss.'" as="style" '.'onload="this.rel='."'".stylesheet ."'".'"'.' >';
        $modx->regClientStartupHTMLBlock($link);
    }

    $moduleJs = $value . 'Js';
    $pathJs = $modx->getOption($moduleJs, $scriptProperties, '', true);
    if( $pathJs != '' ){
        $link = '<link rel="preload" href="'.$pathJs.'" as="script">';
        $script = '<script src="'.$pathJs.'" '.$attrJs.'></script>';
        $modx->regClientStartupHTMLBlock($link.$script);
    }
        	
    
}
Пути к файлам определяются в параметрах сниппета.
Алексей Бгатов
20 января 2018, 05:02
+1
неплохо бы добавить распечатку css в напрямую в код страницы и минификацию самой страницы…
    Максим Кузнецов
    20 января 2018, 07:04
    +1
    case 'OnWebPagePrerender':
    	$html = $modx->resource->_output;
    	$html = preg_replace('|\s+|', ' ', $html);
    	$modx->resource->_output = $html;
    Сергей Шлоков
    20 января 2018, 09:30
    +1
    Хуками, всё хуками. Для наглядности добавил хук cssToPage в пакет. Им можно пользоваться сразу после обновления.
    [[!MinifyX?
        &hooks = `cssToPage.php`
        ...
    ]]]
Сергей Шлоков
20 января 2018, 10:44
+2
Выложил обновление в modStore. Пробуем, комментируем.
terlim
20 января 2018, 10:51
0
Установил пакет — все супер. Правда я отключил минификацию, так как у меня уже собраны минифицированные css и js. Использую для склейки скриптов и стилей дополнений.
Сергей Шлоков
20 января 2018, 16:26
+1
Кому нужно больше примеров.
Сергей Шлоков
21 января 2018, 13:00
+6
Пока далеко не ушёл запилил новую версию. Из основных фич:
— В сниппет добавлены параметры «cssTpl» и «jsTpl», в которых можно указать шаблоны для вывода файла стилей и скриптов.
— Добавлен пункт «print» в параметры «registerCss» и «registerJs» для немедленного вывода файла в месте вызова сниппета.
— Добавлена поддержка настройки «forceUpdate». Сейчас она не используется, так как если вы изменили что-то в файлах, то создается новый файл. Но при разработке это не удобно. На каждое изменение css стиля создается новый файл. За день их может наколбасится огромное количество. Решается указанием полного имени файла (см. ниже).
— Добавлена системная настройка «forceDelete», разрешающая удаление всех файлов в папке. Она используется при очистке кэша. В старой версии удаляются только файлы, соответствующие паттерну для кэш-файлов. А так как в хуках можно переименовывать файлы, то они могут не удалиться при очистке кэша из-за несоответствия паттерну.
— Теперь можно указывать полное имя файла, а не как раньше только префикс («all» или «styles»). Он и будет создан, а не хешированный файл типа «styles_2k784axf49.min.css». Сейчас это можно делать только в хуке. Вот тут и пригодится «forceUpdate».

Ну и так по мелочи. Пока гоняю. К вечеру выложу в modStore.
П.С. Комментарий тянет на целую статью :)
Alexander V
22 января 2018, 16:55
0
ModxMinify такой еще есть.
    Alex Lenk
    25 января 2018, 09:34
    0
    те же яйца, только вид сбоку…

    Некоторые правила CSS требуют пробелов. Например, Bootstrap имеет следующие элементы ввода: height: calc (2.25rem + 2px). «+» Требует пространства с обеих сторон или оно не работает. К сожалению, пробелы разделяются, оставляя входные данные странно.
      Сергей Шлоков
      25 января 2018, 09:42
      0
      ModxMinify использует библиотеку Assetic. Она нормально работает и с «calc» и с «vmax/vmin». Ради эксперимента прикрутил её в MinifyX вместо Munee. Отработала без ошибок.
        Alex Lenk
        25 января 2018, 09:52
        0
        может это проблему и решает, зато остается с пробелами calc (2.25rem + 2px)
Сергей Шлоков
23 января 2018, 09:29
+1
Выпустил новый релиз 1.6.0. Подробности тут.
    Руслан Алеев
    23 января 2018, 14:30
    0
    Здравствуйте, Сергей, спасибо за новую жизнь MinifyX! Заметил одну особенность при обработке css — почему-то в сжатом css отсутствуют стили вида (calc с плюсом), просто вырезаются:
    width:calc(50% + 15px);
    но при этом, если calc с минусом, то стили присутствуют, все нормально:
    width:calc(50% - 15px);
      Сергей Шлоков
      23 января 2018, 18:30
      0
      К сожалению, это опять же проделки css парсера sabberworm/PHP-CSS-Parser, о котором я писал. Видимо его нужно менять. Может знает кто хороший парсер?
        Георгий Пушкин
        07 февраля 2018, 16:52
        0
        Здравствуйте, Сергей.
        Сейчас даже при отключённом сжатии идёт обработка CSS и на выходе получаем вырезанный calc.
        Возможно ли полностью исключить обработку, но склеивать файлы как есть.
          Сергей Шлоков
          07 февраля 2018, 18:11
          0
          Ещё раз. Собирает и обрабатывает css библиотека sabberworm/PHP-CSS-Parser. Она импортирует указанные через import файлы, меняет относительные пути на абсолютные и т.п. Именно она косячит. За минификацию отвечает другая библиотека CSSmin. Она работает как положено.

          Если нужно всего лишь склеить файлы, то напишите простой сниппет, который зачитает указанные файлы и сохранит их в один.
Konstantin
25 января 2018, 21:46
0
Вот уверен что все очень круто, но для дилетантов вроде меня, которые привыкли что из модстор почти все готово к работе из коробки – ничего не понятно.
Главная боль — PageSpeed Insights постоянно ругается на скрипты и стили минишопа, офиса, бутстрапа и даже на jquery который в head подключать надо иначе все перестает работать – что с этим делать?
Может сделать компонент платным, а взамен потратить какое-то время на доработку, подробную документацию и на примеры решения частых проблем?
Василий Столейков
26 января 2018, 17:44
1
+1
А как совместить с MinifiX подключение media-стилей?
Типа такого:
<link rel='stylesheet' href='assets/templates/site/smallscreen.css' type='text/css' media='only screen and (max-width: 768px)' />
    Василий Столейков
    26 января 2018, 17:48
    1
    +1
    Сорри, решил просто добавлением media в сам файл стилей:
    @media only screen 
    and (max-width : 768px) {
    /* Styles */
    }
    Сергей Шлоков
    26 января 2018, 19:13
    +1
    Загляни в параметры сниппета.
Аркадий
29 января 2018, 10:13
0
Даже при включенном параметре minifyx_forceDelete
Удаляются файлы из папки, указанной в системных настройках minifyx_cacheFolder,
при этом из папки указанной в параметре cacheFolder (при вызове сниппета) ничего не удаляется.
    Сергей Шлоков
    29 января 2018, 10:35
    +1
    Настройка forceDelete используется при очистке кэша в админке. Потребность в ней возникла из-за того, что может быть не соблюдена рекомендация использовать отдельную директорию для скомпилированных файлов. И чтобы случайно не удалить посторонние файлы, MinifyX перед очисткой кэша проверяет файлы папки на соответствие шаблону. Прочие файлы игнорируются. А так как я добавил возможность управлять именем скомпилированного файла, то он может также проигнорироваться. Выставляя настройку forceDelete, вы как бы говорите минифаю, что эта папка только для его файлов и он может её полностью очистить.
    Сниппет тут не причем.
      Аркадий
      29 января 2018, 11:20
      0
      Спасибо, я понял. Про forceDelete мне было понятно, просто я имел в виду, что с этим параметром или без него удаление происходит только из папки указанной в системных настройках. Теперь понял, что при очистке кэша в админке плагин не может знать о других папках в которых могут формироваться файлы css
koozoo
29 января 2018, 18:14
0
Calc в CSS всё ещё вырезается?
    koozoo
    29 января 2018, 18:15
    0
    Не увидел вопрос выше, сорри.
ket3er
31 января 2018, 00:24
0
Почему то вывод [[+MinifyX.css]] срабатывает через раз — в одном браузере сайт откроешь — вставляется в html-код сборный css-файл, в другом — как будто и нет его. В журнале ошибок пусто.
    Пётр Молчанов
    31 января 2018, 11:20
    +1
    Проверь, что сниппет вызывается некэшированным, т.е. так [[!MinifyX?
      ket3er
      31 января 2018, 21:52
      0
      Спасибо!
Yar
Yar
31 января 2018, 18:34
0
Два раза все перечитал, но так и не понял: как добавить скрипты и стили компонентов в MinifyX так, что бы они повторно не вызывались на странице самими компонентами?
При таком вызове скрипты/стили компонентов добавляются и в файл /assets/components/minifyx/cache/scripts_da96bb5729.min.js и повторно вызываются на странице самим дополнениями (tickets, PDOtools)
[[MinifyX?
    &minifyCss=`1`
    &minifyJs=`1`
    &registerCss=`default`
    &registerJs=`default`
    &cssSources=`
        assets/template/css/bootstrap.css,
        assets/template/css/style.css
    `
    &jsSources=`
        /assets/template/js/bootstrap.js,
        /assets/components/pdotools/js/pdopage.min.js,
        /assets/components/tickets/js/web/default.js,
        /assets/template/js/move-top.js,
        /assets/template/js/easing.js,
        /assets/template/js/classie.js,
        /assets/template/js/uisearch.js,
        /assets/template/js/share.js,
        /assets/template/js/youtube-no-iframe.js,
        /assets/template/js/copyright.js
    `
    ]]
    Yar
    Yar
    31 января 2018, 18:48
    1
    0
    Такс, с стилями/скриптами Тикета разобрался — отключаем в настройках Тикетс: очистить поля tickets.frontend_css и tickets.frontend_js. А вот по PDOtools вопрос остается открытым
      Алексей Бгатов
      31 января 2018, 19:40
      0
      у сниппета pdopage есть параметры frontend_css и frontend_js, указывайте их пустыми и все будет норм. Или залезьте в набор параметров по умолчанию в админке у сниппета pdopage и укажите там пустые параметры (правда не уверен в данном случае, не потрутся ли параметры при обновлении pdotools). Или создайте свой набор параметров и указывайте его сниппету при вызове
        Yar
        Yar
        31 января 2018, 20:38
        0
        Хорошо, спасибо
Николай
05 марта 2018, 16:35
0
Подскажите, а добавить Source Map к CSS при компиляции LESS, реально?
    Сергей Шлоков
    05 марта 2018, 19:50
    0
    Скорее нет, чем да.
      Wassi Wassinen
      07 мая 2018, 00:35
      1
      0
      Сергей, приветствую. Спасибо за доработки!

      Есть ли возможность оформлять вывод скомпилированных файлов? Есть необходимость добавлять async к
      <script></script>
      .

      Заранее благодарен.
Максим
11 мая 2018, 17:33
0
1) Я так понимаю проблема с calc не решена? calc(100%/2) у меня вырезается.
2) Так же MinifyX при включенном плагине ругается на скрипты miniShop2 и mSearch2. В журнале ошибка:
File does not exist: /assets/components/minishop2/jsdefault.js
Почему-то вырезается из пути "/web/"
3) Можно как-то сделать так, чтобы стили и скрипты подключаемые с других сайтов, автоматически игнорировались при включенном плагине? сейчас прописал регулярку в настройках, но все равно такие файлы не компилируются, поэтому думаю может сразу игнорировать их автоматически?
4) можно разделить папки кеша стилей и скриптов?
Aleksandr Huz
09 июня 2018, 20:13
0
Сергей, добрый день. Как получить значение группы?
Файл группы core/components/minifyx/config/groups.php:
return array(
    'lightgalleryCss' => '/assets/frontend/module/lightgallery/css/lightgallery.min.css',
    'lightgalleryJs' => '/assets/frontend/module/lightgallery/js/lightgallery.min.js'
);
В прехуке, хочу получить значение lightgalleryJs
$url = $MinifyX->getJsGroup('lightgalleryJs');
$url пустой.
    Сергей Шлоков
    10 июня 2018, 09:42
    +1
    Во-первых, группа — это массив файлов.
    Во-вторых, файл groups.php — это репозиторий групп. Он содержит список всех групп. Но они не подключаются. Для подключения группы её нужно указать в соответствующем параметре сниппета. А затем к ней можно обратиться через getJsGroup().
Sergey
09 августа 2018, 13:19
0
А почему шаблон может не отрабатывать?
picplus.ru/img/1808/09/8adfd571.png
    Sergey
    09 августа 2018, 13:30
    0
    а… нет, все ок… сорри