New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assetic is not aware of asset dependencies #79

Closed
matteosister opened this Issue Jun 24, 2011 · 109 comments

Comments

Projects
None yet
@matteosister

matteosister commented Jun 24, 2011

As discussed here there is a problem with the new implementation of the compass binary.
The problem is that, the cache system, checks the timestamp of the sass file without involving the filter.
So if you have a main file which imports other "subfiles" (a typical situation working with compass) and you never edit this main file you never get a recompile.

The process of check the timestamp of an assetic file should in some way involve the filter to get a complete list of files to check and eventually trigger the recompile by checking all the timestamps.

This issue is related to compass, but I think it should also appear in Sass and ScssFilter and also on any filter that deal with an asset with a tree of subassets

@kriswallsmith

This comment has been minimized.

Owner

kriswallsmith commented Jun 24, 2011

I've begun work on this in the mtime-aware branch.

@matteosister

This comment has been minimized.

matteosister commented Jun 24, 2011

is it already testable?

@kriswallsmith

This comment has been minimized.

Owner

kriswallsmith commented Jun 24, 2011

not yet.

On Jun 24, 2011, at 9:01 AM, matteosister
reply@reply.github.com
wrote:

is it already testable?

Reply to this email directly or view it on GitHub:
#79 (comment)

kriswallsmith added a commit that referenced this issue Jul 1, 2011

[GH-79] removed LastModifiedFilterInterface
This is a symptom of a larger issue of asset dependencies that will have to be addressed in a later version.
@srosato

This comment has been minimized.

Contributor

srosato commented Jul 8, 2011

What's the state of this issue? Seems like it was postponed, were there any difficulties?

@kriswallsmith

This comment has been minimized.

Owner

kriswallsmith commented Jul 8, 2011

This is not going to make it into 1.0 unfortunately, but it will probably be the only enhancement in 1.1.

@kriswallsmith

This comment has been minimized.

Owner

kriswallsmith commented Jul 15, 2011

Some open questions:

  • Do filters cascade into an asset's dependencies?
  • How do we differentiate different types of dependencies? (i.e. @import url() vs background: url())
  • This should allow us to apply filters to all images referenced by a stylesheet -- how do we configure that? Based on URL (i.e. \.png$) or something more complex?
  • How will an asset create its dependent assets? Workers (such as Symfony's apply_to) will not fire unless the factory is used.

And probably more...

@kriswallsmith

This comment has been minimized.

Owner

kriswallsmith commented Jul 28, 2011

See #96 also.

@matteosister

This comment has been minimized.

matteosister commented Aug 1, 2011

do you think it's possible to use some native ruby implementation (link this) or plain php to parse line by line the sass/scss files?

@pkruithof

This comment has been minimized.

Contributor

pkruithof commented Nov 24, 2011

What's the status on this issue? Is it possible to disable caching completely (on development environments of course) until this is resolved?

@matteosister

This comment has been minimized.

matteosister commented Nov 24, 2011

disable caching could be a good solution....but I don't think there is a "clean" way to do it...
at the moment I use compass normally as a gem for big projects. For small projects with just few hundreds of line of css code you could use a single file....or remember to change something in the main file if you want assetic to recompile...

@pkruithof

This comment has been minimized.

Contributor

pkruithof commented Nov 24, 2011

This is not always the case: when doing minor CSS tweaking you constantly have to save two files, where you want to be fast switching between editor and browser. I know that tweaking in an inspector is faster and sometimes better, but even then I still switch between editor and browser regularly.

As for small projects: I'm currently working on a project where I keep the media query specific CSS in separate files, and import them at compile time in media queries, but also without media queries for IE<9. There are other use cases to think of where using imports is much more handy, even though the size is not that large.

Edit: this is a separate discussion for a disable-cache flag, obviously. Let's focus on the main issue here. :)

@srosato

This comment has been minimized.

Contributor

srosato commented Nov 24, 2011

The workaround I've been using for the past weeks is "double watching" my files. I fire up the compass watch with a config.rb file to watch for scss file changes, and use assetic to watch on compass' compiled css files. This double watching for now is a bit annoying, but works well until assetic can support dependency watch.

@matteosister

This comment has been minimized.

matteosister commented Nov 24, 2011

@pkruithof I'm using a single file just because of assetic...normally I use only external files, and in my main file I only import things

@srosato So you are not using the CompassFilter..but some css filters (like yui compressor)? It's a shame because compass itself compress css files pretty well....

To me a solution could be: define a list of dependencies given a base file, and assetic should watch all the timestamps.
This could be a quick workaround to the big problem of checking sass files dependencies in php (in ruby it's easy like calling a function)

@srosato

This comment has been minimized.

Contributor

srosato commented Nov 24, 2011

Yeah I know it's a shame for now, yeah I'm using other filters like CssRewrite and YuiCompressor after compass compiled the css files, but not the CompassFilter for now since the asset dependency watching is a must for me. I wish I had a little more time as I would try to give a hand on this issue by contributing.

@matteosister

This comment has been minimized.

matteosister commented Nov 29, 2011

I hope that this pr will bring some quick solution for all these problems...

@ConneXNL

This comment has been minimized.

ConneXNL commented Jan 17, 2012

Also waiting for a solution...

@matteosister

This comment has been minimized.

matteosister commented Feb 1, 2012

@ConneXNL, @srosato here is a solution... CompassElephantBundle

@redemption

This comment has been minimized.

redemption commented Feb 29, 2012

+1 on needing a solution for Less

@matteosister

This comment has been minimized.

matteosister commented Feb 29, 2012

@redemption quick solution waiting for this issue to be closed

https://github.com/matteosister/LessElephantBundle

if you try it please let me know if it works for you.

@schmittjoh

This comment has been minimized.

Collaborator

schmittjoh commented Mar 2, 2012

also related to #190

@matteosister

This comment has been minimized.

matteosister commented Mar 2, 2012

@schmittjoh are there any plans to find a solution for all these problems?
I'm really curious to see what direction assetic will take (assets scan, native binary) and how to implement a filter that can trigger the asset staleness check.
I was hoping that inotify could give a solution....but It's not been merged in sf yet.

@mrclay

This comment has been minimized.

mrclay commented Mar 30, 2012

My plan for Minify is to have smart assets ("sources" in Minify) that know how to linearize and manage watching the dependency files for changes. Internally they would cache the list of dependencies so getLastModified() could simply get the max() of all the dependencies. getContent would re-linearize everything and cache the new list.

This, of course, bypasses all the questions about how dependency files are treated: they're treated as a single asset, period. I'm not all that familiar with LESS yet, but maybe a similar LessLinearizerAsset could do the same thing for LESS: just process the imports and leave the processing for the filter. If LESS requires distinct files for vars I guess this wouldn't work.

@digitalkaoz

This comment has been minimized.

digitalkaoz commented Apr 23, 2012

any updates on this one? its a real showstopper.

@arcanis

This comment has been minimized.

arcanis commented Jun 19, 2012

Isn't there a way to disable the cache in dev environments ?

@matteosister

This comment has been minimized.

matteosister commented Jun 20, 2012

@arcanis I don't think it's a solution, but only a workaround...

@arcanis

This comment has been minimized.

arcanis commented Jun 20, 2012

Didn't say it was a solution. But until we found a solution, it would be great to at least have a workaround.

And actually I think it could be a solution. In a dev environment, why using a cache ?

@matteosister

This comment has been minimized.

matteosister commented Jun 20, 2012

@arcanis because something has to be cached I think. Or you end up waiting for 25 secs for every request. Anyway, don't know if there is a way, and never tried it.
If you find a way and it works without performance issues let me know.

@dotstormz

This comment has been minimized.

dotstormz commented Feb 2, 2014

An example of how to get the supposed fixes working this less would be appreciated. (ie. config settings and filter settings) I've been tinkering for days and this is still an issue.

@unairoldan

This comment has been minimized.

unairoldan commented Jul 24, 2014

I still having problems to use sass in my project; the css files do not recompile with every request in development environment (in this case. scss files).

Is this issue solved for SASS?

Here is my config:

config.yml

assetic:
    debug:          "%kernel.debug%"
    use_controller: false
    bundles:        [ "SystemBundle" ]
    filters:
        cssrewrite: ~
        sass: ~
        compass:
            bin: /usr/local/bin/compass
            apply_to: "\.scss$"
        yui_css:
            jar: "%kernel.root_dir%/Resources/java/yuicompressor.jar"
            apply_to: "\.css$"
        yui_js:
            jar: "%kernel.root_dir%/Resources/java/yuicompressor.jar"

Includes

    {% block stylesheets %}
        {% stylesheets output='/css/main.css'
            '@SystemBundle/Resources/public/sass/main.scss'%}
        <link rel="stylesheet" href="{{ asset_url }}" type="text/css" media="screen" />
        {% endstylesheets %}
    {% endblock %}

main.scss

// Utilities
@import "helpers/variables";
@import "helpers/functions";
@import "helpers/mixins";
@import "helpers/placeholders";

// Base
@import "base/normalize";
@import "base/typography";

// Layout
@import "layout/layout";
@import "layout/header";
@import "layout/footer";

I am using Assetic 1.1 under Symfony 2.5.*

@stof

This comment has been minimized.

Collaborator

stof commented Aug 20, 2014

the issue is resolved for the SassFilter, not for the CompassFilter which is the one you are using. See #640 for the implementation for CompassFilter

@lokhman

This comment has been minimized.

lokhman commented Jan 29, 2015

@stof the issue doesn't seem to be resolved yet for SASS/SCSS.

@sonu27

This comment has been minimized.

sonu27 commented Feb 16, 2015

@stof We are still having this issue for SCSS files.

However, if we disable the asset controller, and watch the files, it does detect changes from @imports.

sass:
            bin:      "/usr/bin/sass"
            no_line_comments: true
            apply_to: "\.scss$"
            http_path: /
            images_dir: %kernel.root_dir%/../web/images
            generated_images_path: %kernel.root_dir%/../web/images
            http_generated_images_path: /images
@kniziol

This comment has been minimized.

kniziol commented Feb 18, 2015

@stof Not working for me. Details below. What should I do now?

/app/config/parameters.yml

# This file is auto-generated during the composer install
parameters:
    (...)
    compass_bin_path: /usr/bin/compass
    nodejs_bin_path: /usr/local/bin/node
    uglifyjs2_bin_path: /usr/local/bin/uglifyjs
    uglifycss_bin_path: /usr/local/bin/uglifycss
    (...)

/app/config/config.yml

# Assetic Configuration
assetic:
    debug:          "%kernel.debug%"
    use_controller: false
    bundles:        [<all required bundles>]
    #java: /usr/bin/java
    filters:
        cssrewrite: ~
        sass: ~
        compass:
            bin: %compass_bin_path%
            node: %nodejs_bin_path%
        uglifyjs2:
            bin: %uglifyjs2_bin_path%
            node: %nodejs_bin_path%
        uglifycss:
            bin: %uglifycss_bin_path%

/src/bundles/MyBundle/Resources/views/Pages/Index/index.html.twig

{% stylesheets output='css/homepage.css' filter='compass, ?uglifycss'
    '@MyBundle/Resources/sass/homepage.scss'
%}
    <link rel="stylesheet" type="text/css" href="{{ asset_url }}" />
{% endstylesheets %}

/src/bundles/MyBundle/Resources/sass/homepage.scss

@import 'common';

.main-content {
(...)

/src/bundles/MyBundle/Resources/sass/_common.scss

//
// Variables: colors
//
$font-color: #4e4b4b;
$dark-blue: #0471CC;
(...)

/composer.json

(...)
    "require": {
        "php": ">=5.3.3",
        "symfony/symfony": "2.6.*",
        "doctrine/orm": "~2.2,>=2.2.3",
        "doctrine/doctrine-bundle": "~1.2",
        "twig/extensions": "~1.0",
        "symfony/assetic-bundle": "~2.3",
        "symfony/swiftmailer-bundle": "~2.3",
        "symfony/monolog-bundle": "~2.4",
        "sensio/distribution-bundle": "~3.0",
        "sensio/framework-extra-bundle": "~3.0",
        "incenteev/composer-parameter-handler": "~2.0",
(...)
@liviucmg

This comment has been minimized.

liviucmg commented Jun 7, 2015

Can confirm that using use_controller: true does not detect changes of @import-ed assets, while use_controller: false + app/console assetic:watch does work.

I also tried using latest dev-master of Assetic, but nothing changed.

@sonu27

This comment has been minimized.

sonu27 commented Jun 8, 2015

@stof @kriswallsmith Could this issue be reopened please?

@perk11

This comment has been minimized.

perk11 commented Sep 4, 2015

Experiencing exactly the same issue as @liviucmg here

@henrypenny

This comment has been minimized.

henrypenny commented Sep 8, 2015

Going off on a tangent here. I'm guessing many people will be using Gulp or Grunt. Adding the ability for assetic:dump to target a single asset will give a lot of people the ability to use those tools to watch for changes while still having assetic work its magic on the individual assets themselves.

E.g.

use Gulp to watch: Resouces/public/sass/**.*,

use assetic (from within Gulp) to dump: Resources/public/scss/main.scss

It will also eliminate the need to re-invent the wheel inside assetic/symfony when there are great tools already available. (Gulp, Grunt)

@moezkorkmaz

This comment has been minimized.

moezkorkmaz commented Dec 9, 2016

Same here. Watching imported assets does not work.

Also I'm not interested in installing Gulp or whatever for just watching the SASS files. I bet there are also others thinking the same. So no need to re-invent the wheel but fixing the issue would be great :-)

@henrypenny

This comment has been minimized.

henrypenny commented Dec 12, 2016

@moezkorkmaz the issue is that Assetic would need to re-invent the wheel by resolving sass imports. Something that is done by libsass if you use gulp.

From the gulp-sass page (https://www.npmjs.com/package/gulp-sass):

gulp-sass is a very light-weight wrapper around node-sass, which in turn is a Node binding for libsass, which in turn is a port of Sass.

There are a couple of libsass wrappers for php:

https://github.com/sass/libsass/blob/master/docs/implementations.md#php

Perhaps these would be a starting point. But it would involve adding an extra php extension to your environment.

@matteosister

This comment has been minimized.

matteosister commented Dec 12, 2016

I would suggest to get rid of assetic and php to manage assets. In my opinion it's not worth it. Better go with javascript and a build tool like webpack or gulp.

@MatthiasKuehneEllerhold

This comment has been minimized.

MatthiasKuehneEllerhold commented Dec 13, 2016

@henrypenny As far as I know Assetic knows about asset dependencies. The sass filter parses the file and resolves all imports in it. See ScssphpFilter::getChildren()

@mpdude

This comment has been minimized.

Contributor

mpdude commented Dec 13, 2016

Forget about Assetic, come up with a build process using front end tools like Gulp and get things like CSS livereload for free. Plus a performance boost on development as Assetic makes Symfony really slow, at least five years ago when I last checked.

@MatthiasKuehneEllerhold

This comment has been minimized.

MatthiasKuehneEllerhold commented Dec 13, 2016

@mpdude Is this your opinion as a maintainer or as an user?

@stof

This comment has been minimized.

Collaborator

stof commented Dec 13, 2016

@MatthiasKuehneEllerhold my recommendation as one of the Assetic maintainers is indeed to switch to a stack built directly using frontend tools if it can fit your workflow.

There are 2 different ways to use Assetic:

  • using only tools written in PHP. But the issue is that most of them are ports of the original tools written in other languages (Node.js for most of them nowadays, but also Ruby or Java for older ones), which are badly maintained and often far behind the original project in term of features because the original project moves very fast.
  • using Assetic filters calling the original tool directly. But then, Assetic is far behind regarding support for configuration settings (as we just don't have resources to update these filters each time one of these projects adds a new option), and it brings no benefit compared to using the tool in a frontend stack (where the integration is generally much better as it is supported by the tool maintainers themselves).

In the second case, my recommendation is clear: stop using Assetic and switch to Gulp or equivalent.
If you are in the first case, consider whether you can switch to the second case, and keep using Assetic otherwise.

Assetic was written at a time available tools were mostly Java and Ruby ones, with no easy way to build a stack combining them automatically. But the ecosystem has evolved a lot since 2011.

@mpdude

This comment has been minimized.

Contributor

mpdude commented Dec 13, 2016

@MatthiasKuehneEllerhold I dug deeper into Assetic a few years ago, also trying to solve this particular issue. I had to learn that it is not worth the hassle and so I can only endorse what @stof says.

As I was mostly using SASS and cssrewrite, the transition over to Gulp was pretty straightforward. I should have a how-to presentation lying somewhere around (in German), email me when you're interested.

@MatthiasKuehneEllerhold

This comment has been minimized.

MatthiasKuehneEllerhold commented Dec 13, 2016

Now thats a grim outlook. We just started a new project and integrated assetic in it. I was worried that it might be abandoned due to 100+ open PRs and no commit for half a year but all the other options weren't as good. I really liked the ZF integration...
Thanks for your opinions!

@stof

This comment has been minimized.

Collaborator

stof commented Dec 13, 2016

@MatthiasKuehneEllerhold lots of opened PR are about adding new filters dealing with more Node.js tools. And as I had few time to dedicate to Assetic these past months (and @kriswallsmith even less than me), adding more filters we don't use and we would have to maintain is not something we rushed about, especially given that we know that they would become outdated a few weeks later when the tool adds new options.

@henrypenny

This comment has been minimized.

henrypenny commented Dec 13, 2016

@MatthiasKuehneEllerhold @stof I had some success writing my own assetic filter some time ago.

https://github.com/henrypenny/hmp-assetic-bundle

Its basically a copy and paste of the cssrewrite filter. But it handles @AppBundle:css/mycss.css references and doesn't require assets:install --symlink.

From memory it was working reasonably well with my use case. I could set up watches in grunt or gulp and get assetic to dump them. But that approach dumps everything at once - css, images, js - which is far too slow.

I wanted to be able to target a single sass file like so:

`app/console assetic:dump '@AppBundle/css/style.scss``

But I didn't get that far.

Targeting single files with assetic:dump would allow assetic to remain lightweight and let other frontend tools do the heavily lifting. But we could still have the benefits that assetic offers with regard to managing frontend resources from multiple bundles etc.

@alex-pex

This comment has been minimized.

alex-pex commented Dec 14, 2016

@stof an alternative I didn't try: https://github.com/romanschejbal/gassetic

@stof

This comment has been minimized.

Collaborator

stof commented Dec 14, 2016

Well, I don't see the benefit of gassetic compared to using gulp directly. Replacing the Gulp config file (which can contain code) with a YAML used to generate it seems to me like it may suffer from the same limitations about tool support (but I may be wrong as I just looked at it quickly).
Thus, it looks like it would have to replace the content of the Twig template when running the command, which looks like a weird integration (and would not allow benefiting from the Symfony Asset component features like cache busting). I think referencing the dumped asset directly rather than adding the gassetic layer.

@henrypenny

This comment has been minimized.

henrypenny commented Dec 14, 2016

@stof how hard would it be to modify assetic:dump to target a single asset - or better still a list of assets?

@stof

This comment has been minimized.

Collaborator

stof commented Dec 15, 2016

Well, there is some challenge here, because asset names in the manager are truncated sha1 hashes by default (and I doubt many people are naming their assets explicitly in Twig, as I'm not even sure we ever documented how to do it). So you would have a hard time passing the argument.

@henrypenny

This comment has been minimized.

henrypenny commented Dec 15, 2016

IMO ideally one would reference assets like this:

app/console assetic:dump @AppBundle:sass/style.scss.

How does assetic resolve @AppBundle:sass/style.scss when templates are parsed?
Surely this logic must already exist?

note: I had some success referencing sass assets like this in an experimental copy of cssrewrite I did a while back.

Do you think this conversation deserves its own issue?

@stof

This comment has been minimized.

Collaborator

stof commented Dec 16, 2016

@henrypenny the issue is that this is not the asset being added in the manager (and so dumped). What you need is to reference the {% stylesheet %} tag added in your template, not a small part of its configuration.

@stof

This comment has been minimized.

Collaborator

stof commented Dec 16, 2016

and yes, please move this to a dedicated issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment