使用 symfony2 clear cache 命令不刷新静态资产

Posted

技术标签:

【中文标题】使用 symfony2 clear cache 命令不刷新静态资产【英文标题】:Static assets not refreshing with symfony2 clear cache command 【发布时间】:2012-07-10 06:34:38 【问题描述】:

我正在使用带有罗盘过滤器的 Assetic 来传递和编译 .scss 文件。这部分设置似乎工作正常。然而,我的理解是,在 app_dev 环境中,Symfony 2 将为每个页面加载重新编译所有资产(包括 css),而不使用它用于 prod 环境的缓存系统。

这似乎没有发生。

当我对 .scss 文件进行更改时,它只有在我使用时才会生效:

 app/console cache:clear

我认为开发环境的重点是避免每次都这样做?!

我已经检查了缓存文件夹的权限(为了安全起见,我已经设置它们以便任何人都可以读取和写入)。有人有什么建议吗?

【问题讨论】:

我将 Symfony 与 less 一起使用,它会在每次请求时重新编译它,只要更改在实际包含的文件中,而不是在从该文件导入的文件中。也许这是你的问题? 【参考方案1】:

资产编译不是缓存系统的一部分。无论环境如何,您都需要在进行更改时重新安装资产。

app/console assets:install web

如果您所在的文件系统支持符号链接,您可以避免每次更改都运行此命令,而是直接安装资产

app/console assets:install web --symlink

但由于您使用的是 Sass,这可能不适合您。

HTH

【讨论】:

对不起,彼得,我应该更清楚。我只是在谈论资产文件(css、js)而不是像图像这样的资产。在文档 (symfony.com/doc/current/cookbook/assetic/asset_management.html) 中,它指出在开发环境中这些资产是动态处理的,并且应该立即看到更改。【参考方案2】:

我想我在这里找到了答案:

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

似乎如果对导入的文件进行了更改而不对父文件进行任何更改,那么父文件将不会被重新编译。在您强制重新编译之前,不会看到更改的结果。

谷歌群组上的海报通过编辑 AsseticController 提出了一个可能的修复(hack!)。我还没有尝试过,但即使它有效,我也不想编辑供应商包。

【讨论】:

【参考方案3】:

我知道这是一个老话题,但我唯一能接受的答案是 CompassElephantBundle 和上面的 AsseticController hack。我有一种方法,本质上但意味着我不必编辑供应商包。

我这样做的方法是编辑复制原始 AsseticController,然后从参数链接到配置中的那个。

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

复制的 AsseticController 只是对源路径中的文件类型进行 preg_match 并从那里更正缓存。

<?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 */

【讨论】:

【参考方案4】:

如果您在开发中使用 symfony 2 资产。环境,只需使用this command:

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

自 2.4 版以来--watch is deprecated,并已被替换为:

php app/console assetic:watch

【讨论】:

详情:symfony.com/blog/… 和 symfony.com/doc/current/cookbook/assetic/asset_management.html【参考方案5】:

我已经在本地开发中解决了这个问题,在我的 parameters.yml 末尾添加了一行,这基本上阻止了任何资产缓存的发生。

# parameters.yml
...

assetic.cache.class: Assetic\Cache\ArrayCache

这应该永远包含在生产环境中,因为我们希望缓存发生!

【讨论】:

【参考方案6】:

我使用不同的方式。我在开发过程中添加所有 .scss 文件

    % block stylesheets %
        % stylesheets filter='?uglifycss' filter='cs-s-rewrite' 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 %  

在我完成开发后,我将它们删除。 这样我就不需要清除我的缓存和添加/更改任何设置。它总是对我有用。

【讨论】:

以上是关于使用 symfony2 clear cache 命令不刷新静态资产的主要内容,如果未能解决你的问题,请参考以下文章

使用 Symfony2 更改 cache_dir 和 log_dir

Symfony2 Travis CI 无法打开文件“/home/travis/build/myname/myproject/app/bootstrap.php.cache”

编辑树枝文件后如何重建网站?

Laravel 5.4 - php artisan cache:使用'file'缓存驱动程序时clear不清除缓存文件

在 Django 中将 cache.clear() 添加到全局保存

Symfony2,Doctrine OneToOne 关系