-
Notifications
You must be signed in to change notification settings - Fork 346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Note: specifying publicPath
in prod can break django-whitenoise / ManifestStaticFilesStorage
#107
Comments
I'm running into this issue as well, only that I can't work around it by taking out Also, at this point, I'd be happy if I can get the resources to be loaded correctly. You mention that |
I put up a possible solution on my own branch here. Basically I added a new config |
@mik3y Preferring The reasoning behind this is that webpack is an independent system and we don't want to force users to couple it to django. Webpack already does everything that whitenoise or other django static collectors do and it does it quite well. So, there is no need for someone to use something like whitenoise in addition to webpack. For such cases, users set the This is very powerful as your frontend team does not even have to deal with Django. They don't even have to run it if they want at any step in the build process. This way webpack and django can be completely decoupled. However, in some cases, we want to use storages, and at that time it is recommended to not set Does that make sense? If so, would you consider this as resolved if this was mentioned in the docs or an FAQ? P.S. I've been planning a refactor that will let users override behavior by writing custom code and hook it up to the webpack loader instance. That change should make it possible to always prefer storage over publicURL in your project if you want. |
@mik3y Also, if you use a static file storage that is capable of doing hashing for long term caching, I would recommend to generate bundles from webpack always without content hashes in their names. Then process those assets/bundles using your static file storage (whitenoise, etc) and let them add the hashes. If you do this, you don't even need django-webpack-loader. Generating assets from webpack without hashes and then treating them as input to whitenoise should let you use django's and whitenoise's API without any need for webpack-loader. |
@owais I can understand why someone would still want to use django-webpack-loader even then. Say you want to build production bundles locally, you'd have a folder for production bundles and one for development bundles, you don't want to have to manually write something like : {% if dev %}
<script src="{% static 'bundles/development/main.js' %}" ></script>
{% else %}
<script src="{% static 'bundles/production/main.js' %}" ></script>
{% endif %} where a single |
This can still be easily solved in about 5 lines of python code. Just need to create a custom template tag that calls either |
Hello, for example: how to make those "webpack_static" load from s3? |
@i-salameh95 what publicPath config do you have in your webpack configuration file? Please share the whole config file if possible. |
@fjsj : this is my Webpack configuration:
|
@i-salameh95 OK, so you're using
As of now, |
First, thanks for this project and your accompanying blog!
I am using
django-whitenoise
with this, which is a derivative of Django'sManifestStaticFilesStorage
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 examplejs/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:
collectstatic
copies both the original resource and its hashed filename to the destination. So bothjs/main.js
andjs/main.536ce6ddaf7b.js
can 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-loader
is called to render a bundle, it determines the URL in one of two ways, depending on thewebpack-stats.json
metadata for the chunk:publicPath
, return that as the URL exactly.staticfiles_storage.url()
for$BUNDLE_DIR_NAME/$CHUNK
.Because my original
webpack.config.prod.js
had a line like like this:... my calls to
render_bundle
would take that first branch & never callstaticfiles_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!)
The text was updated successfully, but these errors were encountered: