Yii2 资源清除缓存

35

每次我在infoweb\menu\module\assets更新我的css或js文件时,我都必须清空backend\web\assets文件夹
有没有一种自动清除缓存的方式?


2
请查看以下链接:http://stackoverflow.com/questions/37723515/why-by-every-refreshing-page-cache-reload-anew/37729758#37729758 - Nana Partykar
8个回答

22

在您的视图中添加以下内容:

use vendor\myVendorName\myPackageName\assets\AppAsset;
AppAsset::register($this);

在您的配置文件中添加以下内容:

'components' => [
    'assetManager' => [
        'linkAssets' => true,
    ], 
]  

清空资产文件夹,刷新,完成


这样做有什么缺点吗?为什么不是默认设置? - robsch
在服务器上,“option followsymlinks”不是默认设置,我认为这可能会导致一些问题:http://stuff.cebe.cc/yii2docs/guide-structure-assets.html#asset-publishing - Ruben
好的。如果您能回答这个问题,还有一件事:新的资产子文件夹(例如“8f02e6b5”)是什么时候创建的?随着时间的推移,我已经有了20多个这样的文件夹。我不知道它们是何时被创建的。它似乎不是每次更改JS文件时都会创建。 - robsch
我认为Yii会为你在视图中注册的每个资产包创建一个资产文件夹,在这个文件夹内,你的js文件会在每次更改时得到更新(如果你使用linkassets => true则不会更新,但你明白我的意思)。 - Ruben
1
注意:在使用linkAssets时,您还可以使用Chrome的“将文件夹添加到工作区”功能,在调试时更改浏览器中的js库。 - ChrisB

18

还有一个额外的属性:

if (YII_ENV_DEV) {
       ...;
       ...;
       ...;
       $config['components']['assetManager']['forceCopy'] = true;
       ...;
       ...;
 }

即使之前已经发布过文件,也要重新发布。


为什么人们不使用像bower或npm这样的包管理器,结合gulp或grunt呢?这样做会更加容易。 - AndrewMcLagan
因为这是Yii2的内置功能 - AssetsBundle。 - Denis Rudov
你可以在Yii中与资产管理器结合使用Bower。 - Ruben
不建议在生产环境中使用forceCopy,因为它非常昂贵(请参见AssetManager::publish()的注释)。 - robsch
3
@robsch说得对,这就是为什么JustSamter的答案建议只在开发环境下启用forceCopy。 - Tom
在哪里编写它,以便在整个项目中都可以应用? - Sami

13

如果您的环境是生产环境,我建议使用缓存失效技术


return [
 // ...
    'components' => [
        'assetManager' => [
            'appendTimestamp' => true,
        ],
    ],
];

了解更多关于资产的信息,请阅读Yii2资产文档


9
如果你正在开发自己的插件,你可以针对每个包强制发行资产(注意:$sourcePath 应该被设置)。
<?php
   namespace app\components\forms\redactorAssets;

   use yii\web\AssetBundle;

   class RedactorCutAsset extends AssetBundle {
      public $sourcePath = '@app/components/forms/redactorAssets/assets';
      public $js = [
        'cut.js',
      ];
      public $publishOptions = [
        'forceCopy'=>true,
      ];
   }

永远不要在扩展中这样做——当第三方插件强制执行此选项时,它会非常恼人。刷新资源是应用程序问题,应该在应用程序级别进行修复。 - rob006
据我记得,这个解决方案仅适用于插件开发阶段。 - grigson

2
sudo rm -rf frontend/web/assets/*
sudo chmod 777 frontend/web/assets
./yii cache/flush-all

如果这不起作用:
sudo rm -rf vendor/*
composer install

1
AssetManager 会根据文件修改时间创建一个哈希值。当目录中的任何文件被更改时,目录的修改时间不会改变。 如果您有一个 AssetBundle,其中包含一个目录作为 $sourcePath,那么将使用目录的修改时间,哈希值不会改变,并且不会将任何内容复制到 web/assets 目录中。
我建议在子类中重写 AssetManager::hash() 或编写一个函数用于 AssetManager::$hashCallback:
'components' => [
    'assetManager' => [
        'hashCallback' => function($path) { 
             // if: $path is directory: figure out when files were changed in directory 
             // else: use original hash function in \yii\web\AssetManager
        }
    ], 
]

如果您想查看一个示例实现,以查找捆绑包中所有资产文件的最大修改日期,可以查看wookie在http://php.net/manual/en/function.filemtime.php#35779中的评论。

请注意,对任何资产文件的修改都将在web/assets中创建一个新目录,并且定期清理仍然是必要的。 但是,除了浏览器缓存之外,刷新页面将遵循最新的更改。


1

我在我的视图文件中使用CClientScript::registerScriptFile方法:

Yii::app()->clientScript->registerScriptFile(
    $this->getAssetsBase() . '/js/script.js'
);

如果我修改了script.js,在下一次页面重新加载后,我将看到所有更改。
对于css文件- CClientScript :: registerCssFile
Yii::app()->clientScript->registerCssFile(
    $this->getAssetsBase() . '/css/style.css'
);

更新:如果您使用的是yii 2.0 beta版本,您可以在此处阅读有关客户端辅助程序机制更改的一些信息:链接


那不是我所需要的。 - Ruben
我在yii2文档中找到了一个特殊的方法publish(),你可以在方法中传递$options参数,并将forceCopy => true作为参数值。这样,你编辑过的文件将被重写到assets文件夹中。链接:http://www.yiiframework.com/doc-2.0/yii-web-assetmanager.html#publish()-detail - itnelo
你能给一个有效路径的例子吗? - Ruben

1
我在main-local.php中为dev环境配置了assetManager::forceCopy=true
return [
'components' => [
    ...
    'assetManager' => [
        'forceCopy' => true,
    ]
    ...
],
];

不要硬编码true/false,可以使用YII_DEBUG常量,在生产环境中将其关闭。 - jakopo87

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接