Usar Assetic para administrar archivos CSS, JavaScript e imágenes

Assetic permite combinar archivos CSS, JavaScript e imágenes y aplicarles filtros antes de devolverlos al navegador

Assetic es una buena opción para administrar los archivos JavaScript, CSS e imágenes de un proyecto Symfony. Los filtros que aplica Assetic permiten transformar dichos archivos y mostrar al usuario unos modificados. ¿Para qué se utiliza? Assetic tiene tres objetivos principales:

  • Minimizar y combinar los archivos CSS y JS.
  • Utilizar un compilador como LESS, SASS o CoffeeScript para ejecutarlos.
  • Optimizar imágenes.

Los archivos se pueden obtener desde la ruta que indiques o desde un bundle.

Incluir archivos CSS con Assetic

{% block stylesheets %}
  {% stylesheets 'bundles/app/css/*' %}
    <link rel="stylesheet" href="{{ asset_url }}" />
  {% endstylesheets %}
{% endblock %}

En lugar de usar la ruta 'bundles/app/css/' puedes emplear la ruta desde un bundle: ' @AppBundle/Resources/public/css/', pero esto causa problemas con el filtro cssrewrite. Si utilizas esta segunda opción asegúrate de añadir el filtro _cssrewrite, _esto evitará que se rompan las rutas relativas:

{% stylesheets '@AppBundle/Resources/public/css/*'  filter='cssrewrite' %}

Incluir archivos JavaScript con Assetic

Se hace exactamente lo mismo pero cambiando "stylesheets" por "javascripts":

{% block javascripts %}
    {% javascripts '@AppBundle/Resources/public/js/*' %}
        <script src="{{ asset_url }}"></script>
    {% endjavascripts %}
{% endblock %}

Incluir imágenes con Assetic

Para incluir imágenes se utiliza la etiqueta "image":

{% image '@AppBundle/Resources/public/img/unaimagen.jpg' %}
<img src="{{ asset_url }}" alt="Una imagen" class="img-circle img-responsive center-block" />
{% endimage %}

Puedes añadirles atributos como en cualquier otra imagen: alt, class, width, height...

Combinar varios archivos con Assetic

Combinar archivos es algo bastante común y útil ya que reduce el número de peticiones HTTP, lo que mejora el rendimiento. Esto también te permite poder dividirlos en tantas partes como desees para una mejor organización. Un ejemplo con archivos JavaScript desde varios bundles:

{% javascripts
    '@AppBundle/Resources/public/js/*'
    '@TiendaBundle/Resources/public/js/shop.js'
    '@UserBundle/Resources/public/js/user.js' %}
    <script src="{{ asset_url }}"></script>
{% endjavascripts %}

En el entorno de desarrollo dev estos archivos no se juntan para poder detectar bugs más fácilmente. En el entorno de producción prod (cuando la opción debug está en false), se mostrará un únito archivo y tag, que contiene a todos los archivos que se ha querido empaquetar. Es importante que para que funcione en el entorno de producción has de decirle a Symfony que genere el archivo individual, mediante el siguiente código:

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

Si después actualizas cualquiera de los archivos que forman el archivo común, tendrás que escribir de nuevo este código.

En cambio en el entorno de desarrollo este proceso se hace de forma automática por defecto. Si quieres cambiar esto (que hace que cargue más lentamente) sólo tienes que modificar un archivo:

# app/config/config_dev.yml
assetic:
    use_controller: false

Así ya no te generará automáticamente los archivos con Assetic y cargará más rápido, pero tendrás que escribir manualmente el siguiente código si haces modificaciones:

php app/console assetic:dump

También puedes usar assetic:watch, que permite regenerar los archivos automáticamente cuando éstos se modifican:

php app/console assetic:watch

Nombrar grupos de archivos con Assetic

# app/config/config.yml
assetic:
    assets:
        jquery_y_jsui:
            inputs:
                - '@AppBundle/Resources/public/js/jq/jquery.js'
                - '@AppBundle/Resources/public/js/jq/jquery.ui.js'

Una vez has nombrado los archivos puedes llamarlos desde la plantilla:

{% javascripts
    '@jquery_y_jsui'
    '@AppBundle/Resources/public/js/*' %}
    <script src="{{ asset_url }}"></script>
{% endjavascripts %} 

Filtros con Assetic

Los filtros te permiten tratar los archivos y modificarlos antes de devolverlos al navegador como respuesta. Los filtros que más se utilizan son para comprimir los archivos para que sean más ligeros, pero también otros como compiladores de JavaScript desde CoffeeScript o procesar SASS en CSS. Es bastante probable que tengas que instalar una librería de terceros para poder aplicar ciertos filtros.

Un ejemplo de filtro es el que ofrece UglifyJS JavaScript minifier, del que hablo más detenidamente en este artículo.

Cambiar la URL que genera Assetic

Puedes personalizar la URL automática que genera Assetic añadiendo el parámetro "output":

{% javascripts '@AppBundle/Resources/public/js/*' output='js/comprimido/principal.js' %}
    <script src="{{ asset_url }}"></script>
{% endjavascripts %}