dotsunited/bundlefu

BundleFu 是一个 PHP 5.3+ 库,可以将多个 CSS/JavaScript 文件打包成一个大的包,并一次性发送。

v1.0.3 2017-12-13 09:31 UTC

This package is auto-updated.

Last update: 2024-09-05 18:44:26 UTC


README

Build Status

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 CompilerService 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();
?>

使用工厂

您还可以使用工厂来创建打包实例。优点是,工厂可以保留全局选项(如 bypassdoc_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_filterjs_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许可证下发布。