views:

147

answers:

6

Often, when working with jQuery, the need arises to include multiple plugins. This can quickly become messy work, especially when some plugins require additional components (images and CSS files).

What are some of the "recommended" ways to:

  • a. Manage the required files/components (.js, .css and images) in a way that is easy to maintain, and;
  • b. Keep these plugin packages updated to the latest versions

I'm not necessarily looking for a tool to do this (although one that could perform this management would be useful, I suppose), but more of a way of thinking.

+2  A: 

I would recommend not updating them unless you are experiencing a problem with the version you have or you would like to use a new feature available in the updated plugin. As the saying goes, if it ain't broke, don't fix it.

Brian
Yeah, you wouldn't want to implement something on your site and have the plugin author deprecate and remove or change a feature you used breaking your page.
Andir
I think the OP's focus is on how to package the scripts and needed resources in a way that is easy to maintain and update - not just on when to update.
rchern
+2  A: 

My own personal "recommended" way is to keep all my JavaScript files in one include folder, all CSS files in another, and all images in a third directory. I write shortcut functions for my projects that I can then use like <?php scriptlink( 'jquery.tooltip' ); ?> or <?php stylelink( 'jquery.thickbox' ); ?>. Each shortcut function takes a filename (only) as an argument and outputs the full HTML tag for that resource type, i.e. (in order) <script type="text/javascript" src="/includes/js/jquery.tooltip.js"></script> or <link rel="stylesheet" href="/includes/css/jquery.thickbox.css" />

Most jQuery plugins I've run across that require images allow either specifying a configuration variable in the script itself or in the code used to invoke the plugin. Stylesheets are quite easily included without mucking about with the script.

So far this method has kept me pretty sane, so I think it works rather well. I don't tear my hair out over where I stuck a particular plugin; I just include it with a function. (The system also supports subdirectories of the include directory, so e.g. <?php scriptlink( 'ui/accordion' ); ?> equals <script type="text/javascript" src="/includes/js/ui/accordion.js"></script>.)

YMMV of course, but the only issue I've had at all is with upgrades when plugin authors start distributing a jquery.plugin.pack.js version instead of jquery.plugin.min.js or vice versa, because I actually have to remember to change the filenames I look for.

(Since I've omitted the implementation of those simple functions, perhaps your version will check for different variants of the file name given. If the argument to scriptlink() is jquery.plugin, the function might check the file system to see if jquery.plugin.pack.js exists, and if not look for jquery.plugin.min.js, and if not look for jquery.plugin.js, etc.)

Voyagerfan5761
+1  A: 

All of my jQuery plugins are organised into subfolders which include the version number e.g.

  • /assets/js/plugin.1.4.1/plugin.1.4.1.min.js
  • /assets/js/plugin.1.4.1/images/image.gif

If I need to update to 1.4.2 I can drop it in a new folder without too many problem, I can even use a specific version of the plugin in different parts of the site if needed. When I site is large and your using a few different plugins it's helpful to quickly see version numbers without digging around source comments in a plugin.js file.

If a plugin requires CSS I will take the base styles out of the plugin CSS and bundle these in with my main stylesheet, requesting additional CSS files is expensive and 9 times out of 10 it will be customised anyway. Likewise with images, if I'm doing any image customisation I will bundle these into my main image sprite, otherwise I'll just link to the images into that plugin.1.4.1 directory.

Yes, you end up with a few more files in your repo but it means:

  • you can easily upgrade plugins just by updating your paths
  • you can debug plugin issues easier because you can see how out of date you are
  • you can roll back to an earlier version if everything breaks
Tom
+1  A: 

You could utilize the Google CDN (Content Delivery Network) for more popular plug-ins. Google keeps it up-to-date, you can quickly choose/switch between versions, and you also get the benefits of caching from other websites that use CDN.

Example for jQuery:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"&gt;&lt;/script&gt;

And, if you want to use a higher version automatically, change the version to 1.4 (automatic 1.4.x updates) or even 1 (automatic 1.x.x updates). Unfortunately not all plug-ins are available, but many of the major ones are.

JasCav
Yep I'm totally down with this, the more I can server from an external CDN the better.
Tom
+5  A: 

I'm surprised no one has covered what I do yet. So here's how I manage scripts and resources.

I have each project I work on setup with SVN. Nearly all of the scripts I include have a SVN mirror (github has svn these days) this means that I can then use SVN externals and fetch whatever branch or version or whatever I want of that project directly into the projects scripts folder. As we are using SVN, it is easy to track, manage and update these scripts.

If a project is not on SVN, then I just add it to a common SVN project I have made, so for instance Project A and Project B, both use jquery-project-not-in-svn, so we stick jquery-project-not-in-svn into our common project's SVN repository, and then use SVN externals on Projects A and B to reference it - as explained before.

Now that covers managing, fetching and updating.

Here is how I cover script inclusions and requests.

As each project now has it's own scripts directory that contains all the scripts it needs (which is managed by SVN externals), we now have to worry about minifying them to reduce load on our server. Each project has a Makefile in it's root, which contains the command update. This command will perform the following:

  • Perform a SVN update (this will update all SVN externals appropriatly)
  • Once that is done, it will pack and minify all the js files into scripts/all.js and scripts/all.min.js

I can't share the exact Makefile but I can share one which is public that handles packing/merging and minification of CSS and Javascript. Here is the link: http://github.com/balupton/jquery-sparkle/blob/9921fcbf1cbeab7a4f2f875a91cb8548f3f65721/Makefile

By doing these things, we have achieved:

  • Management of external script resources over multiple projects
  • Updating of appropriate script resources automatically
  • Packing all used script resources of the project into one file
  • Minifying that file, such that only one JS request and one CSS request are performed.

So good luckmate, feel free to post a comment if you would like to learn more.

balupton
That's a very, very impressive solution. You can beat on me all you want for this: I don't generally use SCM for the projects I work on, so that kind of solution would never have occurred to me. (I'm thinking of starting to use Git, though, but I don't know enough to know if it has a function analogous to SVN's externals.)
Voyagerfan5761
Hehehe, yeah SCM is always soo daunting, but once you start using it - you'll always use it. Git and SVN are both fantastic in their own regards, I use both each day. For all my opensource projects I host them on Github - as github has SVN mirrors for each project what I posted still works - now that's cool! Git has submodules and partial checkouts, but their support is iffy. I still have my projects done in SVN and hosted on Springloops (they have a free plan), as you can't beat SVN externals currently - especially when using software like Cornerstone to manage your projects. :-) Good luck.
balupton
This is exactly the kind of thing I was looking for. I may end up with a slightly different approach (probably using git), but this is a neat idea nonetheless.
Bauer
Thanks mate, I'm really glad I could help! :-) Feel free to write back if you need to know anything more. Here are github's announcements on their SVN mirrors as they really help me when using Git: http://github.com/blog/626-announcing-svn-support and http://github.com/blog/644-subversion-write-support | Another option to look at for using Git could be a projected called Gitternals, instead of Git's Submodules or Partial Checkouts. Good luck :-)
balupton
+2  A: 

CDNs are great but not for debugging. Sometimes debugging really requires local access to the scripts and CDNs are useless until in production mode. For this reason I still like to keep both debug and minified versions around then compare results and benchmark response time until we shift to production.

incidah