解決 Yii2 assets 不自動更新問題

問題描述:core 裏的 Asset (AssetBundle)更新 js 或 css 時,更新內容沒有直接同步到其餘模塊php

-- 若是想節約時間,直接拖到文章底部看結果就好~ css

 

1、項目目錄結構(大概介樣子)html

 

2、需求web

我但願在 core 建一個目錄來管理各模塊共同的 js 和 css(非共同放 backend/web 裏就好)算法

 

3、core 靜態目錄bootstrap

注:$sourcePath 指定靜態文件資源目錄,$css 說明要引入的 css 文件,$js 說明要引入的 js 文件yii2

 

4、具體配置yii

\core\common\config\bootstrap.php函數

Yii::setAlias('@statics', dirname(dirname(__DIR__)) . '/statics');

注:這裏定義上一步 $sourcePath 裏用到的目錄別名spa

 

\core\common\config\main.php

<?php
// 檢查目錄下文件的修改時間
if (!function_exists('_checkfilemtime_')) {
    function _checkfilemtime_($dir, $path, $pathHash) {
        $handle = opendir($dir);
        $hash = '';
        while (false !== ($entry = readdir($handle))) {
            if ($entry === '.' || $entry === '..') {
                continue;
            }
            $file  = $dir . '/' . $entry;

            if (is_dir($file)) {
                _checkfilemtime_($file, $path, $pathHash);
            } else {
                $dist = Yii::getAlias('@backend') . '/web/assets/' . $pathHash . str_replace($path, '', $file);
                if (file_exists($dist) && (filemtime($file)-filemtime($dist))>0) {
                    // 更新文件
                    file_put_contents($dist, file_get_contents($file));
                }
            }
        }
    };
}

return [
    ...
    'components' => [
        ...
        'assetManager' => [
            'hashCallback' => function ($path) {
                // 保持和 vendor\yiisoft\yii2\web\AssetManager.php 裏 hash 函數的算法一致
                $pathHash = (is_file($path) ? dirname($path) : $path) . filemtime($path);
                $pathHash = sprintf('%x', crc32($pathHash . Yii::getVersion()));

                // 處理二級目錄
                if (is_dir($path)) {
                    $path = str_replace("\\", "/", $path);
                    _checkfilemtime_($path, $path, $pathHash);
                }

                return $pathHash;
            }
        ],
        ...
    ]
];

注:

一、Yii2 默認的 asset 管理器只會判斷 assets 內一級文件的修改時候(生成hash值),不會掃描判斷 assets 內二級目錄下的文件。這裏須要自定義處理;

二、須要在配置裏設定 components.assetManager.hashCallback 函數來自定義處理靜態資源的 hash 判斷(返回的 hash 值同樣則不會從新 publish);

三、因此,一個簡單的作法就是:掃目錄,判斷 filemtime,從新生成 hash 值。例如這篇文章說一這樣:https://upliu.net/yii2-assetbundle-does-not-update-auto.html

四、若是直接用 filemtime 從新生成 hash 值,會有一個新問題。那就是 backend/web/assets 下的目錄會愈來愈多(你修改了文件就會生成一個新目錄,但舊目錄不會被刪除)。生成太多無用的舊目錄也是挺讓人頭疼的。

五、因此,個人處理方法是:不改變 return 的 hash 值(不會生成新的目錄),只替換有更新的文件。具體操做請看上面代碼~

 

 https://www.cnblogs.com/tujia/p/11114759.html

 


 完

相關文章
相關標籤/搜索