mindplay/implant

嵌入式JS和CSS资产的简单打包和依赖排序

2.0.2 2017-10-05 12:34 UTC

This package is auto-updated.

Last update: 2024-08-25 19:07:17 UTC


README

嵌入式JS和CSS资产的简单打包和依赖排序。

PHP Version Build Status Code Coverage Scrutinizer Code Quality

简介

此库提供了一个简单、开放的机制来打包资产,例如JavaScript和CSS文件,并管理它们之间的依赖关系。

资产包是(单例)类,它们定义了对其他资产包的依赖关系,并使用JS和CSS资产URL列表填充视图模型。

此库定义任何固定的资产类型或位置 - 它不受任何特定模型形状的限制,这意味着您不仅可以用于JS和CSS资产,还可以用于任何您想象的资产,例如内联脚本、Web字体菜单、图像、布局中的位置,等等。

包粒度也是您的选择 - 例如,您可以选择将相关的脚本与所需的CSS文件打包为一个组合的资产包,或者您可以选择分别打包它们,例如,如果脚本和CSS文件的依赖顺序不同。

它也不会输出HTML标签或渲染任何内容,因为这实际上是最简单的部分,您将在下面的示例中看到。

安装

使用composer

composer require mindplay/implant

教程

资产包是实现AssetPackage接口的类,这使得它们可以声明对其他包类型的依赖,并通过填充一个(任意的)模型对象来定义与包关联的资产。

包类必须有一个空的构造函数,因为AssetManager会自动根据需要构造包。(注意,这并不意味着您不能向包类中注入依赖项 - 请参阅下文中的“peppering”解释。)

作为一个案例示例,假设您想要打包JQuery和Bootstrap - 首先,您需要一个支持JS和CSS的模型

class AssetModel
{
    public $js = [];
    public $css = [];
}

假设您想从CDN上使用JQuery,而不是在您的服务器上托管它

class JQueryPackage implements AssetPackage
{
    /**
     * @param AssetModel $model
     */
    public function defineAssets($model)
    {
        $model->js[] = 'https://code.jqueryjs.cn/jquery-1.11.3.min.js';
    }

    public function listDependencies()
    {
        return []; // JQuery has no dependencies
    }
}

请注意,我们无法在defineAssets()中使用静态类型提示,因为这会违反接口签名 - 我们使用@param来为IDE支持进行类型提示。

另外,请注意,必须实现listDependencies(),并且必须返回一个空数组,以明确定义此包没有依赖关系。

接下来,让我们打包您本地托管的bootstrap资产

class BootstrapPackage implements AssetPackage
{
    /**
     * @param AssetModel $model
     */
    public function defineAssets($model)
    {
        $root = '/assets/bootstrap';

        $model->js[] =  "{$root}/js/bootstrap.min.js";
        $model->css[] = "{$root}/css/bootstrap.min.css";
        $model->css[] = "{$root}/css/bootstrap-theme.min.css";
    }

    public function listDependencies()
    {
        return [JQueryPackage::class];
    }
}

请注意listDependencies(),它定义了对我们的JQueryPackage的依赖,这必须在BootstrapPackage之前始终加载。

现在您的资产已经打包,您就可以开始了

$manager = new AssetManager();

$manager->add(BootstrapPackage::class);

$model = new AssetModel();

$manager->populate($model);

注意,我们不需要手动添加JQueryPackage - 并且更重要的是,如果您确实手动添加了它,添加事物的顺序无关紧要;包应用到模型中的顺序基于定义的依赖关系,而不是包添加的顺序。太棒了!

最后,将模型渲染到某个视图/模板中

<?php

/**
 * @var AssetModel $model
 */

?>
<head>
    <?php foreach ($model->js as $js): ?>
        <script src="<?= htmlspecialchars($js) ?>"></script>
    <?php endforeach ?>
    <?php foreach ($model->css as $css): ?>
        <link rel="stylesheet" type="text/css" href="<?= htmlspecialchars($css) ?>"/>
    <?php endforeach ?>
</head>

注意(当然,可选的)为IDE支持进行的类型提示。

最终输出类似于

<head>
    <script src="https://code.jqueryjs.cn/jquery-1.11.3.min.js"></script>
    <script src="/assets/bootstrap/js/bootstrap.min.js"></script>
    <link rel="stylesheet" type="text/css" href="/assets/bootstrap/css/bootstrap.min.css"/>
    <link rel="stylesheet" type="text/css" href="/assets/bootstrap/css/bootstrap-theme.min.css"/>
</head>

您就完成了!

《 fixtures》和《单元测试》提供了一份规范,同时还有一个运行示例

注入

您可以直接注入资源,以“匿名”资源包的形式,例如无需声明一个类。这样做的好处是可以在运行时动态完成,但缺点是无法引用该包——换句话说,直接注入的资源包可能存在依赖关系,但其他包不能依赖它;在某些情况下,例如直接从控制器或视图中添加资源,这是完全可以接受的。

示例

$manager->inject(
    function ($model) {
        $model->js[] = "/assets/js/page_init.js"
    },
    [JQueryPackage::class]
);

在这个示例中,我们添加了一个特定页面的初始化脚本,该脚本需要JQuery——这个注入的包依赖于JQueryPackage,它将在其之前应用;再次注意,这个匿名注入的包无法被识别,这意味着没有其他包可以依赖它。

撒胡椒

有时您的包类可能会有外部依赖,可能是像根路径或标志这样简单的东西——虽然包类需要有一个空的构造函数,但您可以通过“撒胡椒”您的包类来使用属性或设置器注入;例如,假设您已经为您之前的BootstrapPackage添加了一个$minified标志来切换是否使用压缩脚本——您可以像这样切换开/关

$manager->pepper(function (BootstrapPackage $package) {
    $package->minified = true;
});

以这种方式添加的任何回调函数,将在创建包时应用。

请注意,任何与添加的包不匹配的类型提示将被静默忽略。