Django e Sass com django-compressor

Eu sempre gostei da proposta do django-compressor: Concatenar e comprimir estáticos, utilizando como agrupadores os blocos da engine de templates do Django. Além de manter a declaração dos assets no HTML, ele ainda abre uma margem interessante para quando você precisa customizar um grupo de estáticos para uma determinada página.

Com a chegada dos pré-processadores, como Sass e CoffeeScript, e fatalmente com o advento das ferramentas de build, deixar esse processo para o Django passou a ser questionável. É extremamente razoável passar toda essa responsabilidade para o Grunt, e colocar apenas no seu template Django a URL do estático já "buildado".

Na minha opinião, isso tira um pouco da vantagem descrita no primeiro parágrafo, e adiciona certa complexidade à nossa stack de desenvolvimento. Baseado nisso, e indo na onda da simplificação de build, que eu resolvi devolver esse poder ao Django. E já te adianto: Estou relativamente satisfeito com o resultado!

Concat e minify sem Node.js

O Django Compressor é um app Django que comprime Javascript ou CSS, em um único arquivo cacheável.

Para usá-lo, começamos instalando através do pip:

::shell
$ pip install django-compressor

Na sequência, precisamos adicioná-lo ao arquivo de configuração do seu projeto Django:

::python
# settings.py
INSTALLED_APPS = (
    ...
    'compressor',
    ...
)

Não esqueça de adicioná-lo ao STATICFILES_FINDERS:

::python
# settings.py
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    ...
    'compressor.finders.CompressorFinder',
)

E no seu template Django, utilizamos a templatetag de compressão para CSS e JS:

::html
<!-- index.html -->

{% load compress %}
{% load staticfiles %}

{% compress css %}
    <link rel="stylesheet" href="{% static 'vendor/skeleton/normalize.css' %}" type="text/css">
    <link rel="stylesheet" href="{% static 'vendor/skeleton/skeleton.css' %}" type="text/css">
{% endcompress %}

{% compress js %}
    <script src="{% static 'vendor/jquery/jquery.js' %}"></script>
    <script src="{% static 'js/app.js' %}"></script>
{% endcompress %}

Quando o internauta acessar a sua página, o resultado final será parecido com esse:

<!-- index.html -->

<link rel="stylesheet" href="/static/CACHE/css/0fb9d388202c.css" type="text/css">
<script type="text/javascript" src="/static/CACHE/js/82f4dc99bcc1.js"></script>

Bacana, não? Como a opção COMPRESS_ENABLED é por padrão o inverso de DEBUG, em tempo de desenvolvimento você não verá os assets comprimidos, mas em tempo de QA e produção, se o seu Django estiver corretamente configurado, sim.

Pré-compiladores

Você não precisa do Ruby para utilizar Sass. Hoje, com o advento da especificação do libsass, é possível ter a ferramenta em diferentes linguagens, como Node.js e Python:

::shell
$ pip install libsass

O django-compressor dá suporte a execução de compiladores/transpiladores dado um determinado type. Vamos ilustrar esse cenário com o uso de Sass:

::python
# settings.py
COMPRESS_PRECOMPILERS = (
    ('text/x-sass', 'sassc {infile} {outfile}'),
)

O binário sassc foi instalado no comando pip install acima. O parâmetro infile será o próprio arquivo scss, e outfile será a saída do arquivo, já compilado para CSS.

"Django com estilo!"
Django com estilo!

Agora, a jogada será declarar em nosso template que todas as folhas de estilo escritas em Sass, terão como type o valor text/x-sass:

::html
<!-- index.html -->

{% compress css %}
    <link rel="stylesheet" href="{% static 'vendor/skeleton/normalize.css' %}" type="text/css">
    <link rel="stylesheet" href="{% static 'vendor/skeleton/skeleton.css' %}" type="text/css">
    <link rel="stylesheet" href="{% static 'scss/app.scss' %}" type="text/x-sass">
{% endcompress %}

A partir de agora, no momento de execução do Compressor, além de minificar e concatenar as folhas de estilo, também interpretará arquivos Sass.

Considerações finais

E com isso, mais uma vez, mostramos que é possível ter um projeto web, utilizando ferramentas bacanas (como o Sass), sem necessariamente adicionar uma linguagem diferente à sua stack.

O ideal é que o processo de build seja executado durante o procedimento de deploy do seu projeto (através do comando python manage.py compress). Para isso, é necessário ativar o offline compression do Django Compressor.

No próximo post vamos falar sobre Django + ES6.

Até a próxima...

Referências