Static assets not refreshing with symfony2 clear c

2019-03-25 03:33发布

问题:

I'm using Assetic with the compass filter to pass and compile .scss files. This part of the setup seems to work fine. However, my understanding was that in the app_dev environment, Symfony 2 would recompile all assets (including css) for each page load and not use the caching system that it employs for prod environment.

This seems not to be happening.

When I make a change to a .scss file it will only take effect if I use:

 app/console cache:clear

I thought the whole point of the dev environment was to avoid having to do this each time?!

I've checked the permissions of the cache folders (to be safe I've set them so anybody can read and write). Does anybody have any suggestions?

回答1:

if you are working with symfony 2 assets in dev. environment, simply use this command:

php app/console assets:install
php app/console assetic:dump --watch

Since version 2.4 --watch is deprecated, and has been replaced by:

php app/console assetic:watch


回答2:

I think I've found the answer here:

assetic compass filter, css not updating when changing imported file (google groups discussion)

It seems that if a change is made to an imported file without any changes to the parent file then the parent file will not be recompiled. The result being the change will not be seen until you force recompilation.

The poster on google groups suggested a possible fix (hack!) by editing the AsseticController. I haven't tried it yet, but even if it works I'd rather not edit a vendor package.



回答3:

Asset compilation is not part of the caching system. You need to re-install assets when you make changes, regardless of the environment.

app/console assets:install web

If the filesystem you're on supports symbolic links, you can avoid having to run this command for every change and instead just install the assets as such

app/console assets:install web --symlink

But since you're using Sass, this probably isn't an option for you.

HTH



回答4:

I know this is an old topic but the only answers I could fine were the CompassElephantBundle and the above AsseticController hack. I've got an approach which is essentially but means I didn't have to edit the vendor package.

The way I have done it is to edit copy the original AsseticController and then linking to that in the config from the parameters.

parameters:
    assetic.controller.class: Acme\RandomBundle\Controller\AsseticController

The copied AsseticController just does a preg_match for the filetype from the source path and corrects caching from there.

<?php

/* Original Assetic Controller */

public function render($name, $pos = null)
{
    if (!$this->enableProfiler && null !== $this->profiler) {
        $this->profiler->disable();
    }

    if (!$this->am->has($name)) {
        throw new NotFoundHttpException(sprintf('The "%s" asset could not be found.', $name));
    }

    $asset = $this->am->get($name);
    if (null !== $pos && !$asset = $this->findAssetLeaf($asset, $pos)) {
        throw new NotFoundHttpException(sprintf('The "%s" asset does not include a leaf at position %d.', $name, $pos));
    }

    $bustCache = preg_match('/\.(scss|sass|less)$/', $asset->getSourcePath());

    $response = $this->createResponse();
    $response->setExpires(new \DateTime());

    if ($bustCache) {
        $lastModified = time();
        $date = new \DateTime();
        $date->setTimestamp($lastModified);
        $response->setLastModified($date);
    }
    else
    {
        // last-modified
        if (null !== $lastModified = $asset->getLastModified()) {
            $date = new \DateTime();
            $date->setTimestamp($lastModified);
            $response->setLastModified($date);
        }
    }

    // etag
    if ($this->am->hasFormula($name)) {
        $formula = $this->am->getFormula($name);
        $formula['last_modified'] = $lastModified;
        $response->setETag(md5(serialize($formula)));
    }

    if ($response->isNotModified($this->request)) {
        return $response;
    }

    if ($bustCache) {
        $response->setContent($asset->dump());
    }
    else {
        $response->setContent($this->cachifyAsset($asset)->dump());
    }

    return $response;
}

/* Rest of controller */


回答5:

I have fixed this issue in local development by adding a line to the end of my parameters.yml, which basically stops any asset caching from taking place.

# parameters.yml
...

assetic.cache.class: Assetic\Cache\ArrayCache

This should never be included in a production environment as we want caching to happen!



回答6:

I use different way. I'm adding all .scss files during development

    {% block stylesheets %}
        {% stylesheets filter='?uglifycss' filter='cssrewrite' filter="compass"
            "@TESTSSassBundle/Resources/public/css/_vars.scss" <-- this will be removed
            "@TESTSSassBundle/Resources/public/css/main.scss"
            "@TESTSSassBundle/Resources/public/css/header.scss"
            "@TESTSSassBundle/Resources/public/css/footer.scss"
         %}
            <link rel="stylesheet" href="{{ asset_url }}" />
        {% endstylesheets %}
    {% endblock %}  

and after I finish development I remove them. This way I do not need to clear my cache and add/change any settings. It always work for me.