[Developer says] Using Assetic bundle in Symfony to manage your assets

In this blogpost, my thought was to gather some useful material on how to manage assets on a Symfony project by using the Assetic bundle.

As a project gets bigger, handling more and more assets can become overwhelming. Assetic can help us in organizing where the assets should load, combine multiple assets into a single file, compile assets (e.g. Less or Sass sources into CSS) and even optimize them e.g. by minification.

But first lets start with a Symfony project.

mkdir -p symfony_installation
cd symfony_installation

Download Symfony 2 installer and create a new project:

http://symfony.com/doc/current/book/installation.html

curl -LsS https://symfony.com/installer -o symfony
chmod a+x symfony

./symfony new myproject
cd myproject

Get composer

https://getcomposer.org/download/

curl -sS https://getcomposer.org/installer | php

Install Assetic bundle

https://packagist.org/packages/symfony/assetic-bundle

php composer.phar symfony/assetic-bundle

And now lets install two node packages that will be used with Assetic. nodejs and npm should be installed and in PATH.

Install uglifyjs2 and uglifycss

https://www.npmjs.com/package/uglify-js https://www.npmjs.com/package/uglifycss

npm install -g uglify-js uglifycss

Now we need to enable Assetic to be used in the Symfony project.

Enable Assetic bundle into Symfony

http://symfony.com/doc/current/cookbook/assetic/asset_management.html

File: app/AppKernel.php

public function registerBundles()
{
    $bundles = [
        ...
        new Symfony\Bundle\AsseticBundle\AsseticBundle(),
        ...
    ];

   ...

   return $bundles;
}

And then configure its options.

File: app/config/config.yml

assetic:
    debug:          '%kernel.debug%'
    use_controller: '%kernel.debug%'
    filters:
        cssrewrite: ~
        uglifyjs2:
            bin: /path/to/uglifyjs
        uglifycss:
            bin: /path/to/uglifycss

The filters section shown above is used to register filters that will be available to Assetic during the creation of the production assets. These filters can be used at will and apply transformations into the assets.

cssrewrite is used to correct relative paths into the CSS since the Assetic serves them from different URLs than the intial sources exist.

uglifyjs2 is used to minify the JavaScript files and

uglifycss to minify the CSS files.

All the available filter definitions can be found at: vendor/symfony/assetic-bundle/Resources/config/filters/

The use of Assetic is quite straightforward.

For CSS:

{% stylesheets '@AppBundle/Resources/public/style_1.css'
'@AppBundle/Resources/public/style_2.css'
'@AppBundle/Resources/public/style_n.css'
filter='cssrewrite'
filter='uglifycss'
output='web/cache/styles.css' %}
<link rel="stylesheet" href="{{ asset_url }}">
{% endstylesheets %}

and for JavaScript:

{% javascripts '@AppBundle/Resources/public/script_1.js'
'@AppBundle/Resources/public/script_2.js'
'@AppBundle/Resources/public/script_n.js'
filter='uglifyjs2'
output='web/cache/scripts.js' %}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}

By using the filter argument we apply the desired filters during the creation of the assets. The output argument can be used to define the desired destination output. In the above examples, all the given files will be concatenated and minified into a single file. The {% stylesheets %} and {% javascripts %} blocks will be replaced by <link> and <script> tags during the render of the twig, pointing to the output file.

After clearing the Symfony cache, we can dump the assets for production as follows:

php bin/console assetic:dump --env=prod --no-debug

When using the app_dev environment of Symfony, the assets are updated automatically, but without concatenation and minification. So dumping the assets can be used at the final stages before releasing the code to production.

Thanks for reading so far.