使用PHP类库来合并、编译以及最小化Web Assets

3.4 版本
维护中的版本

从Symfony 2.8开始,Assetic已不再是Symofny标准版框架的自带内容。参考这篇文章以了解如何在你的程序中安装和开启Assetic。

Symfony官方最佳实践推荐使用Assetic来 管理网站资源,除非你精通基于JavaScript的前端工具。

就算以技术视角来看那些前端解决方案是最合适的,使用纯PHP类库在某些场景下仍然有用:

  • 如果你没有安装或使用 npm 以及其他Javascript解决方案;

  • 如果你倾向于限制“使用在自己程序中的不同技术”之种类;

  • 如果你希望简化程序部署。

在本文,你可以学到如何合并和最小化CSS和JS文件,以及如何配合Assetic使用纯PHP类库来编译Sass文件。

安装第三方压缩类库 

Assetic包含了大量“即取即用”的调节器(filters),但却没有包含它们的关联类库。因此,在启用本文提及的调节器之前,你必须安装两个类库。打开控制台,定位到项目目录,执行以下命令:

1
2
$  composer require leafo/scssphp
$  composer require patchwork/jsqueeze

组织你的Web资源文件 

本例包含了一个使用了Bootstrap CSS framework, jQuery, FontAwesome以及其他常见CSS和JavaScript程序文件的设置(其命名为 main.cssmain.js)。这个设置的推荐目录结构看起来像下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
web/assets/
├── css
│   ├── main.css
│   └── code-highlight.css
├── js
│   ├── bootstrap.js
│   ├── jquery.js
│   └── main.js
└── scss
    ├── bootstrap
    │   ├── _alerts.scss
    │   ├── ...
    │   ├── _variables.scss
    │   ├── _wells.scss
    │   └── mixins
    │       ├── _alerts.scss
    │       ├── ...
    │       └── _vendor-prefixes.scss
    ├── bootstrap.scss
    ├── font-awesome
    │   ├── _animated.scss
    │   ├── ...
    │   └── _variables.scss
    └── font-awesome.scss

合并和最小化CSS文件再编译SCSS文件 

首先,配置一个新的 scssphp Assetic调节器:

1
2
3
4
5
6
# app/config/config.yml
assetic:
    filters:
        scssphp:
            formatter: 'Leafo\ScssPhp\Formatter\Compressed'
        # ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- app/config/config.xml -->
<?xml version="1.0" charset="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:assetic="http://symfony.com/schema/dic/assetic"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/assetic
        http://symfony.com/schema/dic/assetic/assetic-1.0.xsd">
 
    <assetic:config>
        <filter name="scssphp" formatter="Leafo\ScssPhp\Formatter\Compressed" />
        <!-- ... -->
    </assetic:config>
</container>
1
2
3
4
5
6
7
8
9
// app/config/config.php
$container->loadFromExtension('assetic', array(
    'filters' => array(
         'scssphp' => array(
             'formatter' => 'Leafo\ScssPhp\Formatter\Compressed',
         ),
         // ...
    ),
));

formatter 选项的值,是被调节器用于生成已编译CSS文件的formatter的FQCN类名。使用压缩的formatter可以令最终文件更小,不管原始文件是常规的CSS文件还是SCSS文件。

接下来,更新Twig模板以添加被Assetic定义的 {% stylesheets %} 标签:

1
2
3
4
5
6
7
8
9
10
11
12
13
{# app/Resources/views/base.html.twig #}
<!DOCTYPE html>
<html>
    <head>
        <!-- ... -->
 
        {% stylesheets filter="scssphp" output="css/app.css"
            "assets/scss/bootstrap.scss"
            "assets/scss/font-awesome.scss"
            "assets/css/*.css"
        %}
            <link rel="stylesheet" href="{{ asset_url }}" />
        {% endstylesheets %}

这个简单的例子,编译、合并和最小化了SCSS文件到一个常规CSS文件,位于 web/css/app.css。这就是提供给你的访客的唯一的CSS文件。

合并和最小化JavaScript文件 

首先,像下面这样配置一个新的 jsqueeze Assetic调节器:

1
2
3
4
5
# app/config/config.yml
assetic:
    filters:
        jsqueeze: ~
        # ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- app/config/config.xml -->
<?xml version="1.0" charset="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:assetic="http://symfony.com/schema/dic/assetic"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd
        http://symfony.com/schema/dic/assetic
        http://symfony.com/schema/dic/assetic/assetic-1.0.xsd">
 
    <assetic:config>
        <filter name="jsqueeze" />
        <!-- ... -->
    </assetic:config>
</container>
1
2
3
4
5
6
7
// app/config/config.php
$container->loadFromExtension('assetic', array(
    'filters' => array(
         'jsqueeze' => null,
         // ...
    ),
));

更新你Twig模板中的代码,添加被Assetic定义的 {% javascripts %} :

1
2
3
4
5
6
7
8
9
10
11
12
<!-- ... -->
 
    {% javascripts filter="?jsqueeze" output="js/app.js"
        "assets/js/jquery.js"
        "assets/js/bootstrap.js"
        "assets/js/main.js"
    %}
        <script src="{{ asset_url }}"></script>
    {% endjavascripts %}
 
    </body>
</html>

这个简单的配置合并了全部JavaScript文件,最小化了它们的内容,并且把新的输出存放在 web/js/app.js 文件中,这就是提供给你的访客的唯一的JS文件。

jsqueeze 调节器名称(filter name)中,开头的 ? 字符告诉Assetic仅在 处于 debug 模式时应用调节器。实践中,这意味着你将在开发过程看到非最小化的文件,而在 prod 环境下则是最小化的文件。

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)