Difference between assetic:dump and assets:install
Asked Answered
T

1

80

In Symfony2, what is the difference between assetic:dump and assets:install? In what scenarios should each of these commands be used, and in what order (if order is relevant)?

Tetraploid answered 4/4, 2014 at 21:16 Comment(0)
D
142

I actually wrote about this recently in an article about OroCRM, which is based on Symfony 2. If you want some of the context/why of the different commands, you might find it interesting.

There are two different systems for including frontend files (javascript, css, images, etc.) in a Symfony application. The assets:install command came first. This command will search all the Symfony Bundles in an application for a

Resources/public

folder. If found, the assets:install command will copy or symlink files from Resources/public to web/public/bundle/[bundle-name]. This is where links created with the twig assets function will look for these files. This

<script src="{{ asset('js/script.js') }}" type="text/javascript"></script>

Becomes this

<script src="/bundles/[bundle-name]/js/script.js" type="text/javascript"></script>

That's all the assets system does. It lets you store your frontend files with the bundle.

The assetic system is different. With assetic, you link to files like this.

{% javascripts '@AcmeFooBundle/Resources/public/js/foo.js' %}
    <script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}

There's similar tags for stylesheets and images. Notice that assetic allows you to link to files in any bundle. (@AcmeFooBundle). Assetic will also let you link to multiple files in a folder with a wildcard.

{% javascripts '@AcmeFooBundle/Resources/public/js/*' %}
    <script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}

Another difference with assetic is in the links generated. In the dev environment they'll look something like this.

<script type="text/javascript" src="/app_dev.php/js/foo.js"></script>
<script type="text/javascript" src="/app_dev.php/js/bar.js"></script>

That is, requests for these files will run through the PHP front controller (app_dev.php) via special routes setup in the assetic bundle. This means, when you're in dev mode, you never need to dump you assets. They're included automatically. It also allows you to apply filters to the files. For example, the following applies the cssrewrite filter to the files pulled in.

{% stylesheets 'bundles/acme_foo/css/*' filter='cssrewrite' %}
    <link rel="stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}

If you ever wanted to programmatically alter the output of your frontend assets — assetic lets you do that by writing custom twig filters.

However, this is performance intensive. In production, instead of linking each file individually via a the PHP front controller file, the generated HTML will look like this

<script type="text/javascript" src="/js/as5s31l.js"></script>

Where does as5s31l.js come from? That's what the assetic:dump command does. It combines all the individual javascript/css files (after applying the filters) and creates a nice, static, cacheable file for production.

What You Need to Do

Unless the project specifically tells you otherwise, you should always run assets:install and assetic:dump, because you'll never know which of your third party bundles use these commands. You only need to run assetic:dump before you deploy or view the application in prod mode. Order is irrelevant.

As for which system your bundle should use — if you've read the above and you're unsure what assetic can do for you, use assets. You'll be fine.

Dybbuk answered 5/4, 2014 at 1:14 Comment(10)
This is a fantastic answer, thank you. I don't believe the distinction is made anywhere in the Symfony docs, and your answer clears things up.Tetraploid
Thanks for clarifying this. Where you stated <script type="text/javascript" src="app_dev.php/js/as5s31l.js"></script> did you actually mean <script type="text/javascript" src="app.php/js/as5s31l.js"></script>Helot
@Sam Probably -- although I might have meant "/js/as5s31l.js" --- I can't remember what Symfony generates and don't have an active project on hand to test.Dybbuk
Thank you too for this answer. If files are served indivitualty throut dev front controller, does this mean that one cannot set a sass filter to process scss files in dev env ?Workshop
@Workshop I'm not familiar with the specific frontend toolchain you're talking about, but the idea behind this system is that assetic could be modified or extended to include SCSS processing.Dybbuk
asset tag does NOT detect the bundle. {{ asset('js/script.js') }} does NOTbecome /bundles/[bundle-name]/js/script.js. Example: symfony.com/doc/master/bundles/FOSJsRoutingBundle/usage.html. You need to define it like this {{ asset('bundles/fosjsrouting/js/router.js') }} which has tells asset tag to look into bundles folderPeeler
from your article "The asset function in the twig template handles converting the asset path to the correct http accessible path." Please test your statement and you'll see is not correctPeeler
@PMoubed The feedback's appreciated, but it was (or at least I'm pretty it was) true at the time I wrote it (over two years ago) If there's a version of Symfony or Oro where the above isn't true, some example code and/or a sample bundle somewhere with a specific set of instructions on how to reproduce the problem would be appreciated.Dybbuk
@AlanStorm I tried it with symfony 2.7 and asset tag did not change it. to reproduce put some assets in Resources/public and run assets:install. You will see the file under web/bundles but if you need to use {{ asset('bundles/bundleName/filename') }}. asset tag is not smart enough to detect the bundle name and what if you had same filename under two different bundle, I think that's why assetics use auto generated file namesPeeler
another good resource on this: symfony.com/doc/current/best_practices/web-assets.htmlPeeler

© 2022 - 2024 — McMap. All rights reserved.