每次重新加载页面时,如何强制资产渲染资产?

Posted

技术标签:

【中文标题】每次重新加载页面时,如何强制资产渲染资产?【英文标题】:How can I force assetic to render assets each time the page is reloaded? 【发布时间】:2012-08-18 00:50:49 【问题描述】:

如何在每次重新加载页面时强制assetic渲染资源(无论资源是否被修改)?

关于我的问题的更多解释:

我目前正在开发一个 Symfony2 项目,我使用 Assetic 来管理和编译 .less 文件。我一切正常,但我有一个小问题需要解决。

在 config.yml 中,我将资产 use_controller 设置为 true。

# Assetic Configuration
assetic:
debug:          %kernel.debug%
use_controller: true

结果是 Symfony 会在每次修改 .less 文件时动态呈现新的 .css 文件。这很棒。

我的问题是我使用了一个主 project.less 文件,我在其中导入了所有其他 .less 文件

// Import Twitter Bootstrap
@import "../../../../../../vendor/twitter/bootstrap/less/bootstrap.less";

// Import Foo
@import "foo.less";

...

它允许我保持一个干净的结构,也可以从供应商那里导入 .less 文件,例如:twitter bootstrap。

在我的 Twig 模板中,我只调用这个主文件。

% stylesheets '@ProjectWebBundle/Resources/public/less/project.less' filter='less' %
        <link rel="stylesheet" type="text/css" media="screen" href=" asset_url " />
% endstylesheets %    

由于这个主 .less 文件从未被修改过,Assetic 不会重新编译资产。这就是为什么我希望无论文件是否被修改,它都能渲染文件。

【问题讨论】:

试试% stylesheets '@ProjectWebBundle/Resources/public/less/project.less' filter='less' debug=true % 感谢您的快速回答@Florent,但这并不能解决问题。 【参考方案1】:

您应该传递给use_controller: false 并在完成后编译您的资产 你的修改。

如果你想编译你的资产:

php app/console assetic:dump

【讨论】:

它有效。但是,这意味着每次修改文件时,我都必须执行该命令。这是一种痛苦。如果我在命令中添加 --watch 参数,那么我会遇到与上述完全相同的问题。【参考方案2】:

我创建了a simple script 来解决这个问题。请尝试一下,如果有帮助,请告诉我。

#!/bin/bash

# assetic-watch: A very simple shell-script to recursively and efficiently
# watch for asset changes and to trigger automatic recompilation.
#
# By Slava Fomin II <s.fomin@betsol.ru>  
# Feel free to contact me.
# From Russia with Love.
# Let's make this World a Better place!
# --------------------------------------

#===============#
# CONFIGURATION #
#===============#

# Path relative to "Symfony/src" directory.
# File changes under specified directory will trigger recompilation
# of all assets.
WATCH_PATH="Name/Bundle/NameBundle/Resources/public/css"

# Environment.
ENV="dev"

# Additional options for "app/console".
OPTS=""

# inotifywait events to watch for.
INW_EVENTS="close_write,moved_to,create"

# Optional inotifywait arguments.
INW_OPTS=""

# Relative path to the Symfony root directory.
SYMFONY_PATH="../"

#============#
# PROCESSING #
#============#

SCRIPT_DIR="$( cd "$( dirname "$BASH_SOURCE[0]" )" && pwd )"
CONSOLE_PATH="$SCRIPT_DIR/$SYMFONY_PATH/app/console"
SRC_PATH="$SCRIPT_DIR/$SYMFONY_PATH/src/$WATCH_PATH"

quietly()  "$@" > /dev/null 2>&1; 

while true; do
    quietly inotifywait --recursive -e $INW_EVENTS $INW_OPTS $SRC_PATH
    php $CONSOLE_PATH assetic:dump --env=$ENV $OPTS
done

我真的希望 Symfony 开发人员能够在 Assetic 捆绑包的未来版本中解决这个问题。我认为这是一个严重的限制。

【讨论】:

我感激不尽。上次我尝试这个时,它对我不起作用,但现在我的环境。有点不同。这是迄今为止唯一可以使用 live.js 自动刷新 @imported CSS 的解决方案。非常感谢!我花了太多时间寻找解决方案,我想我会回到你身边,因为我知道你的剧本很摇滚。它终于得到了回报:-) 哦,谢谢@BrianThomas,我很乐意提供帮助 = ) 我自己不再使用资产,我切换到 Grunt,现在切换到 Gulp 来自动编译我的所有脚本。这是一种非常灵活且强大的资产管理方式。你甚至可以使用 livereload。 我同意,这是一件非常合理的事情。请随时编辑我的答案并添加代码示例。【参考方案3】:

AFAIK目前还没有完美的解决方案

我用:

php app/console assetic:dump --watch

它会在每次检测到模板中引用的任何 .less 文件发生更改时编译您的 .less 文件。

强制进行编译,您必须对“主”文件(@imports 其他文件的文件)进行任何更改。但是,好消息是这足以“触摸”文件来做到这一点。因此,您可以在每次需要时手动触摸它:

touch ~/web/css/main.less;

或者,我通常做的是设置一个脚本,每 60 秒左右接触这个“主”文件:

while true; do
    sleep 60
    touch ~/web/css/main.less
done

这应该适用于 linux 和 mac。

希望对您有所帮助。至少暂时:)

【讨论】:

【参考方案4】:

我正在使用 Assetic 的 Lessphp 过滤器来缓存文件。对于我自己,我创建了一个扩展默认 Assetic 过滤器的类,并使用当前时间触及每个文件

<?php

namespace Xxx\AssetsBundle\Assetic\Filter;

use Assetic\Asset\AssetInterface;
use Assetic\Filter\LessphpFilter;

class LessphpNonCachedFilter extends LessphpFilter

    public function filterLoad(AssetInterface $asset)
    
        $root = $asset->getSourceRoot();
        $path = $asset->getSourcePath();

        $filename = realpath($root . '/' . $path);

        if (file_exists($filename)) 
            touch($filename);
        

        parent::filterLoad($asset);
    

并且您必须在参数部分(services.yml)中设置“assetic.filter.lessphp.class”:

parameters:
    assetic.filter.lessphp.class: Xxx\AssetsBundle\Assetic\Filter\LessphpNonCachedFilter

【讨论】:

注意:触摸需要写权限。您需要确保您的“project.less”文件设置了 xx6 权限。 (我将我的设置为 0666。) 我正在使用LESSnodetouch 原理保持不变,touch 文件(e.g:bootstrap.less) 在您的控制器__construct() - 它会强制重新编译每个页面加载

以上是关于每次重新加载页面时,如何强制资产渲染资产?的主要内容,如果未能解决你的问题,请参考以下文章

无法加载资产颤振(不是资产是保存的文件)

如何在 React 中强制渲染组件

防止在 Yii 框架上使用 ajaxButton/ajaxSubmitButton 加载 jQuery 资产

强制浏览器每次重新加载小程序

使用 Framework7 强制重新加载页面

使用浏览器后退按钮时如何强制重新加载页面?