A strategy for static assets with Bower on Python/Django, Heroku and S3
The case for frontend package management is pretty strong. Once you’ve got jQuery, Bootstrap, half a dozen webcomponents and a few javascript libraries things are getting difficult to maintain and collecting static assets to S3 is taking 45 minutes.
You’ve already given up on the heroku build process and you’re using heroku config:set DISABLE_COLLECTSTATIC 1 and running the collectstatic process as part of your build process like heroku run:detached python manage.py collectstatic –noinput.
So now you’re ready for Bower. There’s a few options like django-bower, but I found this got in the way and gave up many of the benefits of using Bower itself like having a bower.json.
So here’s a different strategy: We’ll collect static assets to S3 directly from your development machine.
Firstly let’s set up Bower. In your project root let’s add your bower.json:
You’ll also need to add a .bowerrc to tell Bower where you’re putting everything:
Also, because we don’t need anything in that directory added to source control (which will slim down your git repository and reduce your slug and build time), add bower_components to your .gitignore.
In .gitignore add:
yourproject/static/bower_components
Next up set up your STATICFILES_DIRS, I found three folders covered it:
In your project settings file:
Run bower update to download all the bower_components and you’re ready to go. Now we need to collect all of our static assets to S3. We can do this using the built-in collectstatic management command:
python manage.py collectstatic --noinput --settings=yourproject.settings.production
This will collect static files from your local machine and upload them to the S3 bucket you’ve configured in your production settings. Here’s how my production static storage is set up:
In yourproject/settings/production.py:
STATICFILES_STORAGE = 'yourproject.utils.storage.StaticStorage'
In yourproject/utils/storage.py:
If you’ve using fig, run it in a detached container like so:
fig run -d web python manage.py collectstatic --noinput --settings=yourproject.settings.production
If you’re using fabric (and you should!), here’s the task:
Hope this helps!