跳到内容

如何为资源使用自定义版本策略

编辑此页

资源版本控制是一种通过向静态资源(CSS、JavaScript、图像等)的 URL 添加版本标识符来提高 Web 应用程序性能的技术。当资源内容发生更改时,其标识符也会被修改,以强制浏览器重新下载它,而不是重用缓存的资源。

如果您的应用程序需要高级版本控制,例如基于某些外部信息动态生成版本,您可以创建自己的版本策略。

注意

Symfony 通过 version、version_format 和 json_manifest_path 配置选项提供了各种缓存清除实现。

创建您自己的资源版本策略

以下示例展示了如何创建与 gulp-buster 兼容的版本策略。此工具定义了一个名为 busters.json 的配置文件,该文件将每个资源文件映射到其内容哈希值

1
2
3
4
{
    "js/script.js": "f9c7afd05729f10f55b689f36bb20172",
    "css/style.css": "91cd067f79a5839536b46c494c4272d8"
}

实现 VersionStrategyInterface

资源版本策略是实现 VersionStrategyInterface 的 PHP 类。在此示例中,该类的构造函数将 gulp-buster 生成的清单文件路径和生成的版本字符串格式作为参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// src/Asset/VersionStrategy/GulpBusterVersionStrategy.php
namespace App\Asset\VersionStrategy;

use Symfony\Component\Asset\VersionStrategy\VersionStrategyInterface;

class GulpBusterVersionStrategy implements VersionStrategyInterface
{
    private string $format;

    /**
     * @var string[]
     */
    private array $hashes;

    public function __construct(
        private string $manifestPath,
        ?string $format = null,
    ) {
        $this->format = $format ?: '%s?%s';
    }

    public function getVersion(string $path): string
    {
        if (!is_array($this->hashes)) {
            $this->hashes = $this->loadManifest();
        }

        return $this->hashes[$path] ?? '';
    }

    public function applyVersion(string $path): string
    {
        $version = $this->getVersion($path);

        if ('' === $version) {
            return $path;
        }

        return sprintf($this->format, $path, $version);
    }

    private function loadManifest(): array
    {
        return json_decode(file_get_contents($this->manifestPath), true);
    }
}

注册策略服务

创建策略 PHP 类后,将其注册为 Symfony 服务。

1
2
3
4
5
6
# config/services.yaml
services:
    App\Asset\VersionStrategy\GulpBusterVersionStrategy:
        arguments:
            - "%kernel.project_dir%/busters.json"
            - "%%s?version=%%s"

最后,感谢 version_strategy 选项,为所有应用程序资源或仅为某些资源包启用新的资源版本控制

1
2
3
4
5
# config/packages/framework.yaml
framework:
    # ...
    assets:
        version_strategy: 'App\Asset\VersionStrategy\GulpBusterVersionStrategy'
本作品,包括代码示例,均根据 Creative Commons BY-SA 3.0 许可获得许可。
目录
    版本