0

When building a reusable app in Django, for example an app that provide a special widget that can be use anywhere, what is the best way to deal with static files needed by the app, but that could be use also by other apps. A good example is jQuery.

If I'm using 3 reusable apps and all of them use and bundle jQuery in their static directory, when loading a page that use all 3 apps, the browser will load 3 times jQuery (probably different versions). That can cause some problems. For example, if the last jQuery to be loaded is an older version and one of the other app need a newest version, that can break this other app. Also it add more download time on the first page load and more requests for each page. That's suboptimal.

So how to built a reusable app to avoid this problem?

Etienne
  • 12,440
  • 5
  • 44
  • 50
  • Write the jQuery plugins to be useable in all versions of jquery, then only include jquery if it isn't already included. – Kevin B Apr 25 '12 at 19:53
  • It's not always easy to write a plugin that works with all versions of jQuery (sometimes your using an already made plugin that need a certain version, etc.) but it could definitely ease the integration. Can you elaborate on how you include jQuery only if it isn't already included? – Etienne Apr 25 '12 at 20:02
  • To include jQuery only if it isn't already included involves first checking if it is included `if ("jQuery" in window)` and adding the script to the page if it isn't `var s = document.createElement('script'); s.src = "jquery.js";document.body.appendChild(s)` As far as the jQuery version compatibility, that just depends on how old the plugins are. Think about it, jquery 1.2.6 was written with the same javascript that jquery 1.7.2 is written on. If it is possible in 1.2.6, it's possible in 1.7.2. The best way to handle this would be for your components to not include their own copy of jQuery. – Kevin B Apr 25 '12 at 20:08
  • OK, I see what you mean for the inclusion. I need to think about the best way to integrate this in the context of a reusable Django app. Thanks for the idea. – Etienne Apr 25 '12 at 20:22

1 Answers1

0

There are three big options that you have (and perhaps you're best served by a combination of them):

  • http://api.jquery.com/jQuery.noConflict/ helps you use jquery without having conflicts over the control of the $ variable.

  • You could use google's CDN version to just include a link? I think this trick is used quite a lot. See Microsoft CDN for jQuery or Google CDN? . You don't end up with multiple copies that way.

  • Don't include jquery yourself, but demand that your code can just use $. Just say that that's a requirement.

Alternatively you could create a basic django app only for including jquery. django-staticfiles helps here. But you probably want to use one of the tips above.

Community
  • 1
  • 1
Reinout van Rees
  • 13,486
  • 2
  • 36
  • 68
  • jQuery was only the most common example. But I need a solution for other files like jQuery-ui (js and css), etc. – Etienne Apr 25 '12 at 20:08
  • If several of your apps depend on a given set of js/css, perhaps my last suggestion is what you want? With django-staticfiles (included in django 1.3+), you can make a basic reusable app that supplies those js/css files and make that "layout app" a dependency of your other reusable apps? I've got just such a package for all our own apps, see https://github.com/lizardsystem/lizard-ui/tree/master/lizard_ui/static as example. – Reinout van Rees Apr 25 '12 at 20:10
  • Maybe it was not clear in my question but when I say "reusable apps" I mean apps that will not only use by my projects but by anyone (like all the apps you find on http://djangopackages.com/). So it also mean that I don't have necessarily the control on all the apps I use in a page because some are apps from others. – Etienne Apr 25 '12 at 20:18
  • Well, then you'll have to bundle it all with your app. And make sure you use that .noConflict() from jquery. And probably use that new-fangled function() wrapper trick in the rest of your js (or use coffeescript) so you don't pollute the global namespace. And all your css rules will have to be limited to just some very specific div ID in your template. Something like that. – Reinout van Rees Apr 25 '12 at 20:21
  • I'm really looking to find/define a way (best practices) that all developers that create public reusable apps should use in such situation. If you look at all the autocomplete apps for Django for example, they all bundle jQuery and al. AND specifying these files in the Media class of their Widget/Admin class. I found this approach less then ideal for the reasons I mention. – Etienne Apr 25 '12 at 20:37