問題描述: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
完