35

Everytime I update my css or js files in infoweb\menu\module\assets, I have to empty the backend\web\assets folder
is there a way to automatically clear the assets cache?

Ruben
  • 8,956
  • 14
  • 63
  • 102
  • 2
    Check this too: http://stackoverflow.com/questions/37723515/why-by-every-refreshing-page-cache-reload-anew/37729758#37729758 – Nana Partykar Jun 09 '16 at 17:54

8 Answers8

22

Add this in your view:

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

Add this in your config:

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

Empty assets folder, and refresh, done

Ruben
  • 8,956
  • 14
  • 63
  • 102
  • Are there any drawbacks with this? Why is this not default? – robsch Dec 05 '14 at 08:34
  • something with 'option followsymlinks' not being a default setting on servers I think: http://stuff.cebe.cc/yii2docs/guide-structure-assets.html#asset-publishing – Ruben Dec 05 '14 at 10:35
  • Okay. One other thing if you can answer this: When is a new assets sub folder (like '8f02e6b5') gets created? Over the time I've got over 20 such folders. And I don't know when they get created. It is not with each change in a JS file as it seems to me. – robsch Dec 05 '14 at 10:59
  • I think yii creates an asset folder for every asset bundle you register in your views, inside the folder is your js file that gets updated every time you make a change (not if you use linkassets => true but you get the point) – Ruben Dec 05 '14 at 13:36
  • 1
    Note: when using linkAssets you can also use chrome's 'add folder to workplace' and change your js library in the browser while debugging it. – ChrisB Oct 20 '15 at 16:41
18

there is additional property as

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

to publish files even there are published before

Denis Rudov
  • 833
  • 8
  • 16
  • Why would'nt people use gulp or grunt, with a package manager like bower or npm...? its just so much easier.... – AndrewMcLagan Apr 26 '15 at 15:15
  • because this is built in functionality of Yii2 - AssetsBundle. – Denis Rudov Apr 29 '15 at 07:41
  • you can use bower in yii in combination with the asset manager – Ruben Jun 18 '15 at 07:34
  • [forceCopy](http://www.yiiframework.com/doc-2.0/yii-web-assetmanager.html#$forceCopy-detail) is not recommended in production as it is very expensive (see note at [AssetManager::publish()](http://www.yiiframework.com/doc-2.0/yii-web-assetmanager.html#publish%28%29-detail)). – robsch Feb 24 '16 at 13:00
  • 3
    That's correct @robsch, that's why JustSamter's answer proposed enabling forceCopy only for the dev environment. – Tom Feb 24 '16 at 17:39
  • Where to write it so it could be applicable throughout the project? – Sami Oct 16 '20 at 07:59
13

If you enviroment is production I recommend to use Cache Busting :

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

for more information about assets, read the Assets Yii2 documentation.

robsch
  • 9,358
  • 9
  • 63
  • 104
Brand Guy
  • 131
  • 1
  • 5
9

If you are developing your own plugin, you can force publish assets per bundle (note: $sourcePath should be set)

<?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,
      ];
   }
grigson
  • 3,458
  • 29
  • 20
  • Never do this in extension - it is super annoying when 3r-party plugin forces this option. Refreshing assets is a app problem and it should be fixed at app level. – rob006 Apr 24 '18 at 07:38
  • as i remember, this solution was for plugin developing stage only – grigson May 04 '18 at 05:06
2
sudo rm -rf frontend/web/assets/*
sudo chmod 777 frontend/web/assets
./yii cache/flush-all

If this does not work:

sudo rm -rf vendor/*
composer install
Pang
  • 9,564
  • 146
  • 81
  • 122
Andrey Bessonov
  • 338
  • 1
  • 7
1

I use CClientScript::registerScriptFile method in my view files:

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

If I modified script.js, after next page reload I will see all changes

For css files - CClientScript::registerCssFile

Yii::app()->clientScript->registerCssFile(
    $this->getAssetsBase() . '/css/style.css'
);

UPDATE: if you use yii 2.0 beta, you can read some information about changes in mechanic of client helpers here: link

itnelo
  • 1,053
  • 2
  • 18
  • 29
  • that's not what I need – Ruben Jul 18 '14 at 07:50
  • I found special method publish() in yii2 doc, you can pass in method $options argument with forceCopy => true, and file which you edited will be rewrited in assets folder, link: http://www.yiiframework.com/doc-2.0/yii-web-assetmanager.html#publish()-detail – itnelo Jul 18 '14 at 07:57
  • can you give an example for a valid path? – Ruben Jul 22 '14 at 13:04
1

The AssetManager will create a hash based on the file modification time. The modification time of a directory does not change when any file is changed. If you have an AssetBundle that has a directory as $sourcePath, the modification time of the directory is used, the hash will not change, and nothing gets copied to the web/assets directory.

I suggest overriding AssetManager::hash() in a subclass or write a function for 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
        }
    ], 
]

For a sample implementation for finding the max modified date over all asset files in a bundle you could look at this comment by wookie @ http://php.net/manual/en/function.filemtime.php#35779

Note that modification to any asset file will create a new directory in web/assets, and regular cleanup will remain necessary. However, browser cache aside, refreshing the page will follow the latest changes.

marvin_x
  • 123
  • 1
  • 4
1

I configure the assetManager::forceCopy=true in main-local.php for the dev environment like this

return [
'components' => [
    ...
    'assetManager' => [
        'forceCopy' => true,
    ]
    ...
],
];
Paul Huo
  • 59
  • 2
  • Instead of harcoding the true/false, you can use YII_DEBUG constant, so it is turned off in production – jakopo87 Jun 27 '18 at 13:21