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


     完

  • 相关阅读:
    微信二维码 场景二维码 用于推送事件,关注等 注册用户 ,经过测试
    简单的 Helper 封装 -- CookieHelper
    简单的 Helper 封装 -- SecurityHelper 安全助手:封装加密算法(MD5、SHA、HMAC、DES、RSA)
    Java反射机制
    Windows Azure Web Site (13) Azure Web Site备份
    Windows Azure Virtual Machine (1) IaaS用户手册
    Windows Azure Web Site (1) 用户手册
    Windows Azure Web Site (12) Azure Web Site配置文件
    Windows Azure Web Site (11) 使用源代码管理器管理Azure Web Site
    Windows Azure Web Site (10) Web Site测试环境
  • 原文地址:https://www.cnblogs.com/tujia/p/11114759.html
Copyright © 2011-2022 走看看