Skip to content

SASS support using django compressor

Saurabh Kumar edited this page May 11, 2016 · 3 revisions

Follow this guide to add SASS support with autoprefix.

Add the following to requirements/common.txt:

# Static files
# -------------------------------------
django-compressor==2.0
django-libsass==0.7
django-compressor-autoprefixer==0.1.0

Create a package.json file at root folder with following content:

{
  "name": "django-compressor-helpers",
  "version": "0.1.0",
  "description": "Installs commandline tools needed by django-compressor for post-processing of css/js.",
  "engines": {
    "node": "5.11.0"
  },
  "dependencies": {
    "autoprefixer": "^6.1.1",
    "postcss-cli": "^2.3.2"
  }
}
INSTALLED_APPS += ('compressor', )

COMPRESS_CSS_FILTERS = [
    'django_compressor_autoprefixer.AutoprefixerFilter',
    'compressor.filters.cssmin.CSSMinFilter',
]

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'compressor.finders.CompressorFinder',
)

COMPRESS_PRECOMPILERS = (
    ('text/x-scss', 'django_libsass.SassCompiler'),
)

COMPRESS_ENABLED = True

Add the following to settings/production.py:

# Compress static files offline
# http://django-compressor.readthedocs.org/en/latest/settings/#django.conf.settings.COMPRESS_OFFLINE
COMPRESS_STORAGE = 'compressor.storage.GzipCompressorFileStorage'
COMPRESS_OFFLINE = True

Edit base.html to add:

{% load compress %}

...

{% compress css %}
<link href="{% static 'css/main.scss' %}"  type="text/x-scss" rel="stylesheet">
{% endcompress %}

...

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

And rename the static/css/main.css to static/css/main.scss.

Update wsgi.py integrate django-compressor with whitenoise:

from whitenoise.django import DjangoWhiteNoise
# ...

class DjangoCompressorWhiteNoise(DjangoWhiteNoise):
    """A sub-class of DjangoWhiteNoise to play nice with django compressor.

    DjangoWhiteNoise by-default doesn't add forever caching headers on the files
    generated with django-compressor as it doen't treat them as immutable. See
    original implementation of `is_immutable_file` for more details.
    """

    def is_immutable_file(self, path, url):
        """Determine whether given URL represents an immutable file.

        Adds a rule to the default implementation so that all the files in the
        COMPRESS_OUTPUT_DIR are recognized as immutable as well.
        """
        is_immutable = super(DjangoCompressorWhiteNoise, self).is_immutable_file(path, url)
        if not is_immutable:
            from django.conf import settings
            if settings.COMPRESS_OUTPUT_DIR in url:
                return True
        return is_immutable

application = DjangoCompressorWhiteNoise(get_wsgi_application())

Heroku Support:

Add the following to bin/post_compile:

# Offline compression of staticfiles via django-compressor
python manage.py compress

Run the following to be able to

heroku buildpacks:set heroku/python --app=<heroku-app-name>
heroku buildpacks:add --index 1 heroku/nodejs --app=<heroku-app-name>

Caveats

Installing autoprefixer binary on travis CI might fail due to older version of nodejs. You can fix that by not using autofixer in the css compiler. Add the following to setttings/testing.py

# Do this here, so that test are run without `postcss` as a requirement.
# Travis CI run with node 0.10.0 which is incompatible with the version
# postcss required.
# This causes the autoprefixer to not run on the complied css.
COMPRESS_CSS_FILTERS.remove('django_compressor_autoprefixer.AutoprefixerFilter')