dotsunited / bundlefu
BundleFu 是一个 PHP 5.3+ 库,可以将多个 CSS/JavaScript 文件打包成一个大的包,并一次性发送。
Requires
- php: >=5.3.0
Requires (Dev)
- phpunit/phpunit: ^4.8.35 || ^5.7 || ^6.4
README
BundleFu 是一个 PHP 5.3+ 库,可以将多个 CSS/JavaScript 文件打包成一个大的包,并一次性发送。
它受到了 Ruby on Rails 插件 bundle-fu 的极大启发。
简而言之,它将这个
<script type="text/javascript" src="/js/jquery.js"></script> <script type="text/javascript" src="/js/jquery.myplugin.js"></script> <script type="text/javascript" src="/js/app.js"></script> <script type="text/javascript" src="/js/app.module.js"></script> <link media="screen" type="text/css" href="/css/reset.css"> <link media="screen" type="text/css" href="/css/jquery.myplugin.css"> <link media="screen" type="text/css" href="/css/app.css"> <link media="screen" type="text/css" href="/css/app.module.css">
转换为这个
<link href="/css/cache/bundle_3f84da97fc873ca8371a8203fcdd8a82.css?1234567890" rel="stylesheet" type="text/css"> <script src="/js/cache/bundle_3f84da97fc873ca8371a8203fcdd8a82.js?1234567890" type="text/javascript"></script>
特性
- 自动检测 CSS 和 JavaScript 文件的修改,并自动重新生成打包文件。
- 可以通过过滤器修改打包内容,例如对 CSS URL 进行重写以避免损坏的图片,对代码进行压缩等。 (库中包含使用 Google Closure Compiler 的 Service API 的过滤器)。
安装
可以使用 Composer 工具安装 BundleFu。您可以将 dotsunited/bundlefu
添加到 composer.json 中的依赖项,或者如果您想将 BundleFu 作为独立版本安装,请进入主目录并运行
$ wget https://getcomposer.org.cn/composer.phar $ php composer.phar install
然后,您可以使用 Composer 生成的自动加载器来访问 BundleFu 类
<?php require 'vendor/autoload.php'; ?>
用法
配置 Bundle 实例
<?php $bundle = new \DotsUnited\BundleFu\Bundle(); $bundle // Set the document root ->setDocRoot('/path/to/your/document_root') // Set the css cache path (relative to the document root) ->setCssCachePath('css/cache') // Set the javascript cache path (relative to the document root) ->setJsCachePath('js/cache'); ?>
或者,您可以在构造函数中传递一个选项数组(或稍后使用 setOptions
方法)
<?php $options = array( 'doc_root' => '/path/to/your/document_root', 'css_cache_path' => 'css/cache', 'js_cache_path' => 'js/cache', ); $bundle = new \DotsUnited\BundleFu\Bundle($options); ?>
使用实例在模板中打包您的文件
<?php $bundle->start(); ?> <script type="text/javascript" src="/js/jquery.js"></script> <script type="text/javascript" src="/js/jquery.myplugin.js"></script> <script type="text/javascript" src="/js/app.js"></script> <script type="text/javascript" src="/js/app.module.js"></script> <link media="screen" type="text/css" href="/css/reset.css"> <link media="screen" type="text/css" href="/css/jquery.myplugin.css"> <link media="screen" type="text/css" href="/css/app.css"> <link media="screen" type="text/css" href="/css/app.module.css"> <?php $bundle->end(); ?>
在您想要的位置输出打包的 <script>
和 <link>
标签
<?php // Renders both <script> and <link> tags echo $bundle->render(); // Renders the <link> tag only echo $bundle->renderCss(); // Renders the <script> tag only echo $bundle->renderJs(); ?>
使用工厂
您还可以使用工厂来创建打包实例。优点是,工厂可以保留全局选项(如 bypass
和 doc_root
),这些选项可以在所有创建的打包中共享
<?php $options = array( 'doc_root' => '/path/to/your/document_root', 'css_cache_path' => 'css/cache', 'js_cache_path' => 'js/cache', ); $factory = new \DotsUnited\BundleFu\Factory($options); // $bundle1 and $bundle2 use the same doc_root, css_cache_path and js_cache_path options $bundle1 = $factory->createBundle(); $bundle2 = $factory->createBundle(); ?>
您可以向 createBundle
方法传递特定选项(全局工厂选项将被覆盖)
<?php $bundle1 = $factory->createBundle(array('name' => 'bundle1', 'doc_root' => '/path/to/another/document_root')); $bundle2 = $factory->createBundle(array('name' => 'bundle2')); ?>
工厂还允许您为过滤器定义名称别名。然后,您可以为 css_filter
和 js_filter
选项定义字符串别名,而不是传递过滤器实例
<?php $filters = array( 'js_closure_compiler' => new \DotsUnited\BundleFu\Filter\ClosureCompilerServiceFilter() ); $factory = new \DotsUnited\BundleFu\Factory(array(), $filters); $bundle1 = $factory->createBundle(array('js_filter' => 'js_closure_compiler')); ?>
过滤器
您可以使用过滤器操作加载的 CSS/JavaScript 文件和打包的 CSS/JavaScript 代码。过滤器是实现 DotsUnited\BundleFu\Filter\FilterInterface
的类。
您可以通过以下方式添加过滤器
<?php $bundle->setCssFilter(new MyCssFilter()); $bundle->setJsFilter(my MyJsFilter()); ?>
如果您需要多个过滤器,您可以使用 DotsUnited\BundleFu\Filter\FilterChain
如此
<?php $filterChain = new \DotsUnited\BundleFu\Filter\FilterChain(); $filterChain->addFilter(new MyCssFilter1()); $filterChain->addFilter(new MyCssFilter2()); $bundle->setCssFilter($filterChain); ?>
默认过滤器
BundleFu 默认提供以下过滤器。
CssUrlRewriteFilter
DotsUnited\BundleFu\Filter\CssUrlRewriteFilter
将 CSS 文件中的相对 URL 重写,以避免损坏的图像引用。
<?php $bundle->setCssFilter(new \DotsUnited\BundleFu\Filter\CssUrlRewriteFilter()); ?>
ClosureCompilerServiceFilter
此过滤器使用 Google Closure Compiler 通过 Service API 编译 JavaScript 代码。
只需添加 DotsUnited\BundleFu\Filter\ClosureCompilerServiceFilter
过滤器,您的 JavaScript 打包就会自动编译
<?php $bundle->setJsFilter(new \DotsUnited\BundleFu\Filter\ClosureCompilerServiceFilter()); ?>
回调过滤器
DotsUnited\BundleFu\Filter\CallbackFilter
可以使用任何PHP回调进行过滤。如果您想使用YUI Compressor压缩CSS,您可以编写自定义过滤器或使用以下代码,利用Callback
过滤器。
<?php $filter = new \DotsUnited\BundleFu\Filter\CallbackFilter(function($content) { $descriptorspec = array( 0 => array('pipe', 'r'), // STDIN 1 => array('pipe', 'w'), // STDOUT 2 => array('pipe', 'a') // STDERR ); $handle = proc_open('java -jar /path/to/yuicompressor.jar --type css' , $descriptorspec, $pipes); if (is_resource($handle)) { fwrite($pipes[0], $content); fclose($pipes[0]); $compressed = stream_get_contents($pipes[1]); fclose($pipes[1]); proc_close($handle); if ($compressed) { return $compressed; } } return $content; }); $bundle->setCssFilter($filter); ?>
注意
-
在
$bundle->start()
和$bundle->end()
之间所有的内容都将丢失。请确保只在此块中放置css/javascript包含。 -
通过解析输出并查找包含文件来检测脚本和样式表。HTML注释被忽略,因此如果您像这样注释掉一个脚本:
<!-- <script src="/js/script.js" type="text/javascript"></script> -->
该注释将被忽略,文件仍然会被打包。请确保通过PHP进行注释。
<?php /* <script src="/js/script.js" type="text/javascript"></script> */ ?>
-
通过查询字符串加载的外部依赖项将不会工作。
<script src="/js/scriptaculous.js?load=effects,controls" type="text/javascript"></script>
相反,您需要像平常一样包含每个JavaScript文件。
许可证
BundleFu在MIT许可证下发布。