enjoys/assets-collector

资产收集器 CSS 和 JS

2.5.0 2023-09-23 18:20 UTC

README

7.4 8.0 8.1 8.2 Scrutinizer Code Quality Build Status Code Coverage

安装

composer require enjoys/assets-collector

使用

环境配置

use Enjoys\AssetsCollector\Assets;
use Enjoys\AssetsCollector\Environment;

//project directory
$projectDir = __DIR__;
//compile path relative project directory
$assetsDir = $projectDir .'/assets'; 
//or relative project directory
//$assetsDir = 'assets';

$environment = new Environment($assetsDir, $projectDir); 
//Base URL to compile path for Web
$environment->setBaseUrl("/assets-collector/example/assets"); 
//Set strategy, default STRATEGY_MANY_FILES
$environment->setStrategy(Assets::STRATEGY_ONE_FILE); //Assets::STRATEGY_MANY_FILES
//Cache time for files in strategy STRATEGY_ONE_FILE
$environment->setCacheTime(0); //cache time in seconds
//Adds the output version, for example //example.php/style.css?v=123 
$environment->setVersion(123);
//You can change the parameter for the version
$environment->setParamVersion('?ver=');

/** 
 * YYou can add a logger that implements \Psr\Log\LoggerInterface, for example, Monolog
 * @var \Psr\Log\LoggerInterface $logger 
 */
$environment->setLogger($logger);

CSS Minify 配置

JS Minify 配置

初始化类

/** @var \Enjoys\AssetsCollector\Environment $environment */
$assets = new \Enjoys\AssetsCollector\Assets($environment);

添加到集合

如果第三个参数传递了命名空间,则在输出时也需要写上它。这是一种分组方式。

/** @var \Enjoys\AssetsCollector\Assets $assets */
$assets->add('css', [
    'style/style.css', //относительный путь, относительно текущей рабочей директории
    __DIR__ . '/style/style.css', //полный путь
    '//example.com/style.css', //сокращенная URL ссылка
    'https://example.com/style.css', //URL ссылка
    'url:/assets/css/style.css', // URL ссылка
    'local:/assets/css/style.css', // URL ссылка (local: и url: идентичны)
    ['style.css', \Enjoys\AssetsCollector\AssetOption::MINIFY => false], //попускает минификацию конкретного файла
    ['goods/style.css', \Enjoys\AssetsCollector\AssetOption::REPLACE_RELATIVE_URLS => false], //не заменяет относительные ссылки - оставляет так как есть
]);

额外参数

可以将资源链接作为数组传递,其中数组的第一个元素是路径,后面的元素是参数。

use Enjoys\AssetsCollector\AssetOption;

/** @var \Enjoys\AssetsCollector\Assets $assets */
$assets->add('css', [
    [
         __DIR__.'/style.css',
         // По-умолчанию все ресурсы минифицируются, если указать явно false, этот ресурс пропустит минификацию
         AssetOption::MINIFY => false,
         
         // Если нужно создать дополнительные симлинки, то можно указать их в этом параметре, в качества массива,
         // где ключ - сама ссылка, а значение - исходный файл или директория (цель)
         // Это бывает необходимо если в ресурсе есть относительные ссылки, и чтобы был к ним доступ нужно прописать
         // явно все символические ссылки
         AssetOption::SYMLINKS => [
            __DIR__.'/symlink' => __DIR__.'/../../../target',
            //...
        ],  
        
        // При STRATEGY_MANY_FILES будут добавлены html-аттрибуты,
        // примерно это будет выглядеть так
        // <script attribute-key='attribute-value' attribute-without-value attribute-without-value src='...'>
        AssetOption::ATTRIBUTES => [
            'attribute-key' => 'attribute-value',
            'attribute-without-value' => null,
            'attribute-without-value-another-method',
            //...
        ],
        
        // При STRATEGY_ONE_FILE если будет установлена эта опция в true, то именно этот asset в сборку не попадет,
        // а выведется отдельно
        AssetOption::NOT_COLLECT => true,   
         
        // При false - не заменяет относительные ссылки - оставляет так как есть.
        // По-умолчанию true, все относительные ссылки заменяются на абсолютные
        AssetOption::REPLACE_RELATIVE_URLS => false       
    ],
    //...
]);

在构建 assets 时,所有资源都会按照它们进入集合的顺序收集,就像之前一样,默认情况下。但可以通过更改 \Enjoys\AssetsCollector\Assets::add 中的最后一个参数来选择将 assets 插入集合的方式,即 pushunshift

这在模板中很有用,比如在 twig 模板中,在主模板中连接通用样式,然后在子模板中连接特定样式,在这种情况下,使用 push,通用样式将位于特定样式之下连接,而使用 unshift,则先连接通用样式,然后是特定样式,尽管 twig 仍然会按照从子模板到通用模板的顺序处理它们

  • push - 默认值,将数据插入到集合末尾
  • unshift - 将数据插入到集合开头。
/** @var \Enjoys\AssetsCollector\Assets $assets */
$assets->add($type = 'css|js', [], $namespace, $method = 'push|unshift');

输出

/** @var \Enjoys\AssetsCollector\Assets $assets 
 */
$assets->get('css'); //get Css with default namespace
$assets->get('js', 'admin_namespace'); //Get Js with namespace `admin_namespace`

$environment->setStrategy(Assets::STRATEGY_ONE_FILE); 时,会读取所有文件并将它们写入一个文件。返回用于连接样式或脚本的 HTML 字符串

<link type='text/css' rel='stylesheet' href='/assets/3c2ea3240f78656c2e4ad2b7f64a5bc2.css?_ver=1610822303'/>

$environment->setStrategy(Assets::STRATEGY_MANY_FILES); 时,将返回单独的样式或脚本,这在开发时很有用

<link type='text/css' rel='stylesheet' href='/assets/bootstrap.min.css?_ver=1610822303'/>
<link type='text/css' rel='stylesheet' href='https://example.com/style.css?_ver=1610822303'/>

对于 JS,所有操作类似,除了输出时不包含 HTML

Twig 扩展

连接扩展

/** 
 * @var \Twig\Environment $twig 
 * @var \Enjoys\AssetsCollector\Assets $assets
 */
$twig->addExtension(new \Enjoys\AssetsCollector\Extensions\Twig\AssetsExtension($assets));

在模板中添加到集合

下面展示了如何在模板中连接资源。

请注意,不完整的路径将是相对于当前工作目录或项目目录的

 {{  asset('css', [{0: 'https://cdn.jsdelivr.net.cn/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.css', 'minify': false}]) }}
 {{  asset('css', 'https://cdn.jsdelivr.net.cn/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.css') }}
 {{  asset('js', ['path/script.js', 'script.js'], 'namespace') }}

从版本 2.2.1 开始支持 twig 路径

在初始化扩展时,需要传递一个实现 \Twig\Loader\LoaderInterface 的加载器,例如 \Twig\Loader\FilesystemLoader

/** 
 * @var \Enjoys\AssetsCollector\Extensions\Twig\AssetsExtension $extension 
 * @var \Enjoys\AssetsCollector\Assets $assets
 * @var \Twig\Loader\LoaderInterface $loader
 */
$extension = new AssetsExtension($assets, $loader));

在模板中的输出

{{ eCSS() }}
{{ eJS('namespace') }}

CSS Minify 配置

默认情况下,使用 NullMinify::class 作为压缩器,即不进行压缩。要安装压缩器,在 Environment 中使用方法 Environment::setMinifyCSS(MinifyInterface $minifyImpl)

基本的 CSS Minify 实现是通过库 tubalmartin\CssMin 实现的。详细参数说明:https://github.com/tubalmartin/YUI-CSS-compressor-PHP-port#api

可以很容易地使用其他库来实现压缩,只需实现接口 \Enjoys\AssetsCollector\Content\Minify\MinifyInterface::class

use Enjoys\AssetsCollector\Content\Minify\Adapters\CssMinify;

/** @var \Enjoys\AssetsCollector\Environment $environment */
//необязательно передавать все параметры, можно только выборочно 
$environment->setMinifyCSS(
    new CssMinify([
        'keepSourceMapComment' => false, //bool
        'removeImportantComments' => true, //bool
        'setLineBreakPosition' => 1000, //int
        'setMaxExecutionTime' => 60, //int
        'setMemoryLimit' => '128M',
        'setPcreBacktrackLimit' => 1000000, //int
        'setPcreRecursionLimit' => 500000, //int
    ])
);

JS Minify 配置

默认情况下,使用 NullMinify::class 作为压缩器,即不进行压缩。要安装压缩器,在 Environment 中使用方法 Environment::setMinifyJS(MinifyInterface $minifyImpl)

基本的 CSS Minify 实现是通过库 JShrink 实现的。更多信息:JShrink

可以很容易地使用其他库来实现压缩,只需实现接口 \Enjoys\AssetsCollector\Content\Minify\MinifyInterface::class

use Enjoys\AssetsCollector\Content\Minify\Adapters\JsMinify;

/** @var \Enjoys\AssetsCollector\Environment $environment */
// Необязательно передавать все параметры, можно только выборочно 
$environment->setJsMinifyOptions(
    new JsMinify([
        'flaggedComments' => false
    ])
);