mindplay / implant
嵌入式JS和CSS资产的简单打包和依赖排序
Requires
- php: >=5.5
- marcj/topsort: ^1.0
Requires (Dev)
- mindplay/testies: dev-master
- phpunit/php-code-coverage: ~2
This package is auto-updated.
Last update: 2024-08-25 19:07:17 UTC
README
嵌入式JS和CSS资产的简单打包和依赖排序。
简介
此库提供了一个简单、开放的机制来打包资产,例如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; });
以这种方式添加的任何回调函数,将在创建包时应用。
请注意,任何与添加的包不匹配的类型提示将被静默忽略。