Download - Building a JavaScript Library
![Page 1: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/1.jpg)
Building aJavaScript Library
John Resig (ejohn.org)jQuery JavaScript Library / Mozilla Corporation
August 18th, 2007 - Google Tech Talk
![Page 2: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/2.jpg)
jQuery✦ Released Jan. 2006✦ Focus on DOM Traversal✦ Built in support for Events, Ajax, and
Animations✦ Succinct code, small file size✦ Extensible via a plugin architecture
![Page 3: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/3.jpg)
jQuery Samples✦ $(“#main div”).addClass(“test”);
✦ $(“#main”).slideDown(“slow”);
✦ $(“ul > li”).click(function(){ $(this).find(“ul”).toggle();});
✦ $(“#contents”).load(“doc.html”);
![Page 4: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/4.jpg)
Doing something right?✦ ~25 people on the jQuery Team✦ 1/4 million visitors per month
✦ Fantastic Growth (via Google Trends)
![Page 5: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/5.jpg)
FUEL✦ To be included in Firefox 3✦ A JavaScript library for extension
developers✦ Provides helpers for: Browser tabs,
bookmarks, events, preferences✦ Written in pure JavaScript, extensible
![Page 6: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/6.jpg)
FUEL Samples✦ Application.prefs.all.forEach(function(p){
if ( p.modified ) // do something});
✦ Application.events.addListener(“quit”, fn);
✦ Application.browser .open("http://google.com/").active = true;
✦ Application.bookmarks.all.forEach(function(cur){ if ( cur.url.match(/google.com/) ) cur.remove();});
![Page 7: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/7.jpg)
Need to know:✦ Writing a Solid API✦ Implementation✦ Complex Applications✦ Browser Bugs✦ Documentation✦ Testing✦ Maintenance
![Page 8: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/8.jpg)
Writing A Solid API
![Page 9: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/9.jpg)
Orthogonal✦ Perform Universal Actions✦ CRUD your methods!
add/remove/delete/modify✦ FUEL has the following on every object:
✦ .all, .add(...), .remove(...), .get(...)✦ jQuery was missing .removeAttr() for the first couple months (oops!)
✦ Made a grid for FUEL, filled in the blanks
![Page 10: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/10.jpg)
Fear Adding Methods✦ Methods can cause a support nightmare✦ Avoid adding, if you can✦ Defer to extensibility✦ jQuery:
✦ Added .top(), .left(), .background()✦ Duplicate of .css() - unnecessary
![Page 11: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/11.jpg)
Embrace Removing Code✦ Remove un-used code✦ Reduces the size of your API✦ Reduces your filesize✦ Make your code more maintainable✦ jQuery: Ran a poll to remove CSS 3
selectors.✦ Reduced size of the API by 47% in 1.1
![Page 12: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/12.jpg)
Provide an Upgrade Path✦ Expect compatibility changes✦ Provide transitional plugin✦ Plugin for jQuery 1.1, for jQuery 1.0 users (+ documented in 3 languages)
![Page 13: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/13.jpg)
Reduce to a common root✦ Look for common patterns✦ Reduce to its core and build up✦ jQuery:
✦ .eq(0), .gt(3), and .lt(2)✦ why not just implement slice?
.slice(0,1) or .slice(1,4)
![Page 14: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/14.jpg)
Consistency✦ Users can “expect” good naming✦ Pick a naming scheme and stick with it
✦ .click() vs .onclick()✦ Argument position
✦ .method( options, arg2, ..., callback )✦ Callback context
✦ .method(function(){ // this == DOMElement});
![Page 15: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/15.jpg)
Implementation
![Page 16: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/16.jpg)
Evolution of a JavaScript Coder
✦ “Everything is a reference!”✦ “You can do OO code!”✦ “Huh, so that’s how Object Prototypes
work!”✦ “Thank God for closures!”
![Page 17: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/17.jpg)
Functional Programming✦ Closures are essential✦ Understand this snippet:
✦ (function(){ // your code...})();
✦ Great for ‘local variables’✦ Perfect for macros
✦ var event = [‘click’,’focus’,’blur’,...];jQuery.each(event,function(i,name){ jQuery.prototype[name] = function(fn){ return this.bind(name,fn); };});
![Page 18: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/18.jpg)
Quick Tip: Local Vars✦ (function(){
// your code... var test = false;
this.method(function(){ return test; });}).call(this);
✦ Locally-scoped variables✦ Access to instance
![Page 19: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/19.jpg)
Encapsulation✦ Contain all of your code to a scope✦ Hide your code and prevent it from
leaking✦ All of your code should be wrapped in a:
✦ (function(){ // your code...})();
✦ BONUS! Your code compresses really well with Dojo Compressor, et. al.
![Page 20: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/20.jpg)
Namespacing✦ Use as few global variables as feasible✦ One namespace is optimal(see: Dojo, Yahoo UI, jQuery, MochiKit)
✦ Questions to ask:✦ Can my code coexist with other random
code on the site?✦ Can my code coexist with other copies
of my own library?✦ Can my code be embedded inside
another namespace?
![Page 21: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/21.jpg)
Don’t Extend Native Objects✦ Down this path lies great pain and
suffering✦ Impossible to get DOM extensions
working cross-browser✦ Object.prototype kills kittens✦ JS 1.6 methods cause conflicts:
✦ elem.getElementsByClassName✦ array.forEach, .map, .filter
![Page 22: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/22.jpg)
Perform Type Checking✦ Make your API more fault resistant✦ Coerce values wherever possible
✦ .css(Number) becomes:.css(Number + “px”)
✦ .map(String) becomes:.map(new Function(String))
✦ Error messages✦ Quite useful✦ Byte-costly✦ Solution: Move to ‘debugging’ extension
![Page 23: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/23.jpg)
Quick Tip for OO✦ Tweak your Object constructor✦ function jQuery(str, con){
if ( window == this ) return new jQuery(str, con); // ...}
✦ Make it easier for users:new jQuery(“#foo”) becomes:jQuery(“#foo”)
![Page 24: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/24.jpg)
Quick Tip for Errors✦ Never gobble errors✦ Ignore the templation to try{...}catch(e){}
✦ Improves debug-ability for everyone
![Page 25: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/25.jpg)
Complex Applications
![Page 26: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/26.jpg)
Extensibility✦ Your code should be easily extensible
✦ Methods: jQuery.fn.method = fn;$(...).method();
✦ Selectors: jQuery.expr[‘:’].foo = “...”;$(“:foo”)
✦ Animations: jQuery.easing.easeout = fn;.animate({height: 100}, “slow”, “easeout”);
✦ Write less, defer to others✦ Makes for cleaner code✦ Foster community and growth
![Page 27: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/27.jpg)
Pure OO Code✦ Object-Oriented is only one answer✦ JavaScript != Java✦ Not a good solution
✦ At least not until JavaScript 2✦ Classes, Packages, etc.
![Page 28: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/28.jpg)
Custom Events✦ The answer lies in custom events✦ Dojo, jQuery, Yahoo UI - just added to
Prototype✦ Components trigger events and listen for
others✦ .bind(“drag”,fn)✦ .trigger(“refresh”)
![Page 29: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/29.jpg)
Browser Bugs
![Page 30: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/30.jpg)
The Quirksmode Problem✦ Fantastic resource✦ Tells you where problems are✦ Doesn’t tell you how to fix them✦ Need to focus on problem sets
✦ Events✦ Get Attribute✦ Get Element Style
![Page 31: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/31.jpg)
Solving a Problem✦ Some issues are solved in depth
✦ DOM Events✦ DOM Traversal
✦ Many still require hard work:✦ getAttribute✦ getComputedStyle
✦ Permute your test cases, look for edge cases
![Page 32: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/32.jpg)
When to run the fix✦ Typical thought progression:
✦ “I’ll just look at the useragent”✦ “I’ll just detect to see if an object exists”✦ “I’ll just think of an elegant solution to
the problem”✦ “I’ll just look at the useragent”
![Page 33: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/33.jpg)
Documentation
![Page 34: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/34.jpg)
Structured✦ Provide a clear format✦ Users can build new views with it
✦ No API view is perfect✦ jQuery users built:
✦ API browsers✦ Cheat sheets✦ Widgets✦ Translations
✦ An API for your API!
![Page 35: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/35.jpg)
Users Want to Help✦ Make barrier to helping very low✦ Answer: Keep your docs in a wiki✦ Only do this if you’ve already written all of
your docs✦ Wiki != Documentation
✦ Use templates to maintain structure
![Page 36: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/36.jpg)
Focus on Leverage✦ Write the docs that will get the most
benefit✦ Rough Priority:
✦ User-centric API✦ Plugin authoring✦ Docs on writing docs✦ Advanced plugin authoring
![Page 37: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/37.jpg)
Write the Docs Yourself✦ It isn’t glamorous, but it’s essential✦ You must buckle-down and do it yourself✦ Improves your longevity and uptake
![Page 38: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/38.jpg)
Testing
![Page 39: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/39.jpg)
1000% Essential✦ Don’t trust any library that doesn’t have a
test suite✦ Good: Prototype, MochiKit, jQuery,
Yahoo UI✦ Write your own suite (they’re pretty easy)✦ Be sure to handle async tests
✦ Ajax✦ Animations
✦ Pass in all supported browsers
![Page 40: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/40.jpg)
Test-Driven Development✦ Write test cases before you tackle bugs✦ Find devs who love to write test cases✦ Check for failures before commit✦ Pure JS DOM (running in Rhino) can help
spot obvious errors✦ pre_commit hook in SVN, if you can
*cough* Google Code *cough*
![Page 41: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/41.jpg)
Future of Testing✦ Distributed Multi-Browser Testing✦ How it works:
✦ Report results back to central server✦ Server pushes new tests/code to clients✦ Repeat
✦ jQuery and Prototype are very interested in this (expect something soon)
✦ Test against browser nightlies✦ See: JS lib test cases in Mozilla trunk
![Page 42: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/42.jpg)
Maintenance
![Page 43: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/43.jpg)
Tackling New Bugs✦ Create a rapid test environment
✦ ./gen.sh bugnum (dom|ajax|selector|...)✦ Your test suite must be passing✦ Have good coverage✦ Always test in all supported browsers to
avoid regressions✦ Check unsupported browsers before
release✦ Don’t want them to crash/error out
![Page 44: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/44.jpg)
Use Your Community✦ Use your community as a sounding board
✦ Gauge the usefulness of features✦ Users are great for finding weird edge cases✦ Pay attention to repeat questions
✦ Indicative of problem in API design✦ or lack of documentation
![Page 45: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/45.jpg)
Maintain Focus✦ Very, very, important✦ Users generally choose libraries for
ideological reasons✦ Breaking your ideology will alienate your
users✦ jQuery: Small, concise, code. Small
download, light core, easily extensible.✦ Use plugins to divert functionality from
your core
![Page 46: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/46.jpg)
More Details✦ Contact Me:
[email protected]✦ More details:
✦ http://ejohn.org/✦ http://jquery.com/✦ http://wiki.mozilla.org/FUEL
![Page 47: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/47.jpg)
Fun
![Page 48: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/48.jpg)
Fun With One Liners✦ “I’m not suggesting that one-liners are the heart of all programming. But
they can be the hook to get someone exploring. A single line of code simply shows that a language can be focused. And it lets a beginner get comfortable with the basic atoms.” - _why
✦ jQuery allows for fantastic one liners
![Page 49: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/49.jpg)
One-Liners✦ $("div.section")
✦ $("div.section").removeClass("section").hide();
✦ $("div.section") .find("dt") .addClass("section") .click(function(){ $(this).next().toggle(); }) .end() .find("dd") .hide() .filter(":first") .show() .end() .end();
![Page 50: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/50.jpg)
One-Liners✦ Remove unsightly anonymous functions!✦ $("div.section")
.find("dt") .addClass("section") .onclick() .next().toggle().end() .end() .end() .find("dd") .hide() .filter(":first") .show() .end() .end();
![Page 51: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/51.jpg)
Domain-Specific Language✦ $("div.section")
find("dt") addClass("section") click( next() toggle() ) end() find("dd") hide() filter(":first") show() end() end()
![Page 52: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/52.jpg)
Domain-Specific Language✦ $("div.section"
find("dt" addClass("section") click( next( toggle()))) find("dd" hide() filter(":first" show())))
![Page 53: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/53.jpg)
Domain-Specific Language✦ Lisp-y!✦ ($ "div.section"
(find "dt" (addClass "section") (click (next (toggle)))) (find "dd" (hide) (filter ":first" (show)))))
![Page 54: Building a JavaScript Library](https://reader034.vdocuments.net/reader034/viewer/2022050613/586fd3e21a28ab18428b4685/html5/thumbnails/54.jpg)
Domain-Specific Language✦ Python-y!✦ div.section:
dt: addClass "section" click next toggle dd: hide :first: show
✦ Give it a try:http://ejohn.org/apps/jquery2/
✦ Secret Sauce:<script type=”text/jquery”>...</script>