Confident Asset Deployments with Webpack & Django, part 4

Confident Asset Deployments with Webpack & Django, part 4

 django-logo-positive 

In the previous post in this series, we've described how at Stratasan, we integrate our Webpack builds into our main Django application. By moving the specific links to our Javascript and CSS out of our Django templates and instead using django-webpack-loader to render these tags, our deployments become more stable and less error-prone.

We want to finish this series with a few niceties that we've built for ourselves to improve our process of delivering valuable software to our clients.

Delivering Files via S3

We deliver all of our front-end assets via S3. While S3 is not as performant as true CDN, it is extremely easy to upload files via boto. We use the S3 storage backend from django-storages to ultimately reference all files from our assets bucket in S3.

After our bundle build process, we automatically upload our bundles to the S3 bucket configured to serve our static files.

 

Testing the Stats Files

While testing our front-end application is an entirely separate topic, we do integrate two tests into our test run to 1) make sure that the Webpack stats files were committed after a successful build, and 2) that the bundle to which these stats files will link is accessible from the internet.

The first test function looks like this:

from glob import glob
import json
from os.path import join

def verify_bundle(bundle):
assert 'error' not in bundle
assert 'status' in bundle
assert bundle['status'] == 'done'
assert bundle['status'] != 'error'

def test_bundle_content():
# Make sure all of the ../static/webpack-stats-*.prod.json files are valid bundles
for stats_file in glob(join(APP_DIRECTORY, 'static', 'webpack-stats-*.prod.json')):
with open(stats_file, 'r') as fp:
bundle = json.loads(fp.read())
try:
verify_bundle(bundle)
except AssertionError:
msg = '{}' is not a bundle that should be deployed'
raise AssertionError(msg.format(stats_file))

This simple test loops through all of our Webpack stats files and verifies that the build did not fail. If it did, it raises a more useful error message to inspect.

The second test is a little more advanced and actually uses django-webpack-loader to render the paths to the bundles as done when the template renders in production.

Because this uses Django settings, the test case must be a class overriding SimpleTestCase.

import requests
from django.test import SimpleTestCase, override_settings
from webpack_loader.templatetags.webpack_loader import get_files

class BundleRenderTestCase(SimpleTestCase):

def verify_accessible(self, url):
# Make a GET request for the specified URL and raise for non-200 status
requests.get(url).raise_for_status()

@override_settings(
DEBUG=False,
STATIC_URL='https://s3.amazonaws.com/yourbucket/static/',
AWS_STORAGE_BUCKET_NAME='yourbucket',
)
def test_render(self):
config = settings.WEBPACK_LOADER
for name, bundle_config in config.items():
for ext in ('js', 'css'):
try:
url = get_files(name.lower(), ext, name)[0]['url']
except IndexError:
# This is ok, just means extension isn't produced in bundle
self.verify_accessible(url)

For each key, value pair in the WEBPACK_LOADER settings, this attempts to find all files in the bundle that end with either js or css and renders the actual path to the asset with django-webpack-loader. Then, a GET request is made using the wonderful requests package. If the status on the HTTP response comes back as non-200, an error will be thrown and the test will break.

 

Wrapping Up

We hope you've enjoyed our series on how we deploy front-end assets to our users. This process allows our front-end developers to use modern tools to develop Javascript and CSS and provides a simple, efficient and easy means to deploy those files while integrating with our Django application.

Below are links to the previous posts, in case you've missed one in this series.

Part 1Part 2Part 3

 

Article by Scott Burns, VP of Engineering for Stratasan

If you would like to learn more about Stratasan and how we could equip your team to maximize strategic growth potential, email us at sales@stratasan.com

Connect with Stratasan on LinkedIn or follow Stratasan on Twitter and Facebook.

app application Blog code coding developer developers Django DjangoCon engineer Engineering health care healthcare Javascript tech technology web