- 
                Notifications
    
You must be signed in to change notification settings  - Fork 342
 
Description
First, thanks for this project and your accompanying blog!
I am using django-whitenoise with this, which is a derivative of Django's ManifestStaticFilesStorage storage backend that adds forever-cacheable headers. All worked well except I noticed for some reason my bundle asset (let's call it $STATIC/js/main.js) was not being served correctly, unlike all other static assets.
In general, in this kind of setup, collectstatic transforms files by adding a content hash for the file name, for example js/main.js might be copied to $STATIC_ROOT/js/main.536ce6ddaf7b.js. The hashes are transparently added by the staticfiles backend, so a URL like {% static 'js/main.js' %} should automatically be translated to the hashed URL when served/rendered. For some reason, render_bundle did not do this.
It turns out there are two unrelated behaviors that are at play here:
- 
collectstaticcopies both the original resource and its hashed filename to the destination. So bothjs/main.jsandjs/main.536ce6ddaf7b.jscan be served by the application — which in my case masked the fact that the hashed file was never being served (i.e. nothing in the app breaks, it just doesn't get the nice caching features). - 
When
django-webpack-loaderis called to render a bundle, it determines the URL in one of two ways, depending on thewebpack-stats.jsonmetadata for the chunk:- If the chunk has a 
publicPath, return that as the URL exactly. - Otherwise, call 
staticfiles_storage.url()for$BUNDLE_DIR_NAME/$CHUNK. 
 - If the chunk has a 
 
Because my original webpack.config.prod.js had a line like like this:
config.output.publicPath = '/static/js/';... my calls to render_bundle would take that first branch & never call staticfiles_storage.url, returning the "plain" unhashed asset. The fix is simple: remove thepublicPath config.
In summary: Don't set output.publicPath in prod unless you know what you're doing; webpack loader will not consult your staticfiles backend if you do.
(PS: I'm guessing this isn't actionable, my apologies if this obvious to more webpack-savvy folks. I'm pretty unfamiliar with webpack/django guts, so I figured I'd splat some notes here for searchability if nothing else, in case another noob trips up like I did. cheers!)