Saturday, March 17, 2012

Porting jQuery Plugins to Zepto: Tips & Tricks

As I've written about it here in the past I've spent a fair amount of time porting jQuery plugins to work with Zepto, a lightweight alternative with a smaller API surface. You can read those posts here and here to see how I ported specific plugins over, but today I thought I'd give a general guide for people taking on the task of porting other plugins over. There are an approximate shit ton of jQuery plugins out there (it was basically the defacto way of creating Javascript UI widgets for the last few years), so I see a lot of porting in our future. Here's the strategy I employ:

  1. Start by setting up your page so you can easily switch between serving jQuery and serving Zepto, and modify the last line of the plugin code to work with either:
    })(window.jQuery || window.Zepto);
  2. Test your code with Zepto, and look for errors in the logs about undefined methods. That means the plugin is using a method that is not in your Zepto.js, and you need to either not use that method or more likely, find a way to define it in your Zepto copy:
    1. Do a CTRL+f on the Zepto docs to see if the method is described there. Sometimes it's defined in the optional files, and you just have to bring those into your copy (like the data() and animate() methods).
    2. Look up the method in the jQuery docs and read the description. Some jQuery methods are very similar to other methods, and can be safely substituted in some situations (like contents() and children().)
    3. Search the Zepto issue tracker to see if other developers have filed an issue about lacking functionality. If they have, they often include a patch or link to a gist which you can copy into your Zepto copy.
    4. Check the jQuery source code (either using this source browser or by CTRL+Fing in the uncompressed source code) to see how they accomplish the functionality, and bring that code into your Zepto copy. Just think carefully about how much of that code you actually need for the modern mobile browsers, and whether there are edge cases you can safely remove.
  3. Once you've gone through the undefined errors, you might think your plugin is good to go — but then you try to use it and it just doesn't do what you expect it to. Don't worry, there's still hope yet! Sometimes a plugin uses an existing jQuery method but uses it with optional arguments or alternative constructors, and that can lead to code behaving differently when run on jQuery versus Zepto. To see if that's happening, place strategic console.log statements around the code, run it with both jQuery and Zepto, and see where variable values differ. When you find a misbehaving area of the code, look carefully at the arguments that the plugin is sending into a method, compare that to what Zepto is accepting (both type and number). If you discover a discrepancy, follow the steps above to supplement your Zepto copy to handle the other method usage.
  4. Now that you've hopefully successfully ported a plugin, contribute it back to the community. At the very least, stick it in a gist with "Zepto + PLUGIN-NAME" and tweet it, or even better, write a blog post explaining the changes, and contribute patches to Zepto (of additions) and/or the plugin (of subtractions/simplifications). You may find that the Zepto authors don't want to bloat the library with that functionality, and you might find that a plugin author doesn't care about making their code play nicer with lighter weight jQuery alternatives, but it doesn't hurt to put your patches out there.

And if all else fails (or if porting is just taking too damn long) — find a library that does what you want, but doesn't rely on jQuery. Or write it yourself. Happy porting!

No comments: