跳到內容

如何為 Assets 使用自訂版本策略

編輯此頁

資源版本控制是一種技術,透過將版本識別符新增至靜態資源(CSS、JavaScript、圖片等)的 URL,來提升 Web 應用程式的效能。當資源的內容變更時,其識別符也會被修改,以強制瀏覽器再次下載,而不是重複使用快取的資源。

如果您的應用程式需要進階的版本控制,例如根據某些外部資訊動態產生版本,您可以建立自己的版本策略。

注意

Symfony 透過 versionversion_formatjson_manifest_path 設定選項,提供各種快取失效實作。

建立您自己的 Asset 版本策略

以下範例示範如何建立與 gulp-buster 相容的版本策略。此工具定義了一個名為 busters.json 的設定檔,該檔案將每個資源檔案對應到其內容雜湊值

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

實作 VersionStrategyInterface

資源版本策略是實作 VersionStrategyInterface 的 PHP 類別。在此範例中,該類別的建構子接受由 gulp-buster 產生的 manifest 檔案路徑和產生的版本字串格式作為引數

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 授權條款發布。
目錄
    版本