zoukankan      html  css  js  c++  java
  • 解决 Yii2 assets 不自动更新问题

    问题描述:core 里的 Asset (AssetBundle)更新 js 或 css 时,更新内容没有直接同步到其他模块

    -- 如果想节约时间,直接拖到文章底部看结果就好~ 

    一、项目目录结构(大概介样子)

    二、需求

    我希望在 core 建一个目录来管理各模块共同的 js 和 css(非共同放 backend/web 里就好)

    三、core 静态目录

    注:$sourcePath 指定静态文件资源目录,$css 说明要引入的 css 文件,$js 说明要引入的 js 文件

    四、具体配置

    corecommonconfigootstrap.php

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

    注:这里定义上一步 $sourcePath 里用到的目录别名

    corecommonconfigmain.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) {
                    // 保持和 vendoryiisoftyii2webAssetManager.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


     完

  • 相关阅读:
    hdu 2089 不要62(初学数位DP)
    字符串与整数之间的转换
    字符串之判断重复字符串
    字符串之全排列
    字符串之移位
    链表
    STL之map
    海量数据处理
    字符串之strchr
    字符串之_strncat
  • 原文地址:https://www.cnblogs.com/tujia/p/11114759.html
Copyright © 2011-2022 走看看