解决 Yii2 assets 不自动更新问题
问题描述:core 里的 Asset (AssetBundle)更新 js 或 css 时,更新内容没有直接同步到其他模块
-- 如果想节约时间,直接拖到文章底部看结果就好~
一、项目目录结构(大概介样子)
二、需求
我希望在 core 建一个目录来管理各模块共同的 js 和 css(非共同放 backend/web 里就好)
三、core 静态目录
注:$sourcePath 指定静态文件资源目录,$css 说明要引入的 css 文件,$js 说明要引入的 js 文件
四、具体配置
\core\common\config\bootstrap.php
Yii::setAlias('@statics', dirname(dirname(__DIR__)) . '/statics');
注:这里定义上一步 $sourcePath 里用到的目录别名
\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 (!is_dir(dirname($dist))) { mkdir(dirname($dist), 0755, true); } // 两个文件的修改时间相差5分钟及以上,则重新生成文件 if (!file_exists($dist) || (filemtime($file)-filemtime($dist))>=300) { 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; } ], ... ] ];
注:
1、Yii2 默认的 asset 管理器只会判断 assets 内一级文件的修改时候(生成hash值),不会扫描判断 assets 内二级目录下的文件。这里需要自定义处理;
2、需要在配置里设定 components.assetManager.hashCallback 函数来自定义处理静态资源的 hash 判断(返回的 hash 值一样则不会重新 publish);
3、所以,一个简单的做法就是:扫目录,判断 filemtime,重新生成 hash 值。例如这篇文章说一这样:https://upliu.net/yii2-assetbundle-does-not-update-auto.html
4、如果直接用 filemtime 重新生成 hash 值,会有一个新问题。那就是 backend/web/assets 下的目录会越来越多(你修改了文件就会生成一个新目录,但旧目录不会被删除)。生成太多无用的旧目录也是挺让人头疼的。
5、所以,我的处理方法是:不改变 return 的 hash 值(不会生成新的目录),只替换有更新的文件。具体操作请看上面代码~
https://www.cnblogs.com/tujia/p/11114759.html
完