All of my projects include very similar tasks and quite recently I've been thinking I should write a library to handle most of the heavy lifting so I can write short, simple, easy to read code that interacts with the library to get the jobs done. Looking at other frameworks, specifically jQuery & YUI, they work in different ways. jQuery mostly seems to extend & simplify the DOM using a global object/function whereas YUI uses namespaces and modules. I understand that this is because they have different goals as libraries and each have their merits.
Most specifically, I'm looking for answers to the following questions:
Is it best to use namespaces, eg gui.scrollbar.attach(), or a global method such as $(domObj).attachScrollbar()?
Is it best to include individual parts as seperate js files or as a single js file where components are copied/pasted? I know the eBay Shopping API SDK has many .js files in seperate folders, wouldn't this suffer a significant performance hit?
Is there any other advice you would give to someone looking to create a javascript library?
I've marked as community wiki because I didn't want to risk the question being closed - I'm genuinely seeking advice here.
Thanks
EDIT
I should have originally stated that I'm not re-inventing the wheel, I'm looking to simplify many common tasks between Windows Desktop Gadgets, so I don't need the cross-browser compatibility of other libraries and their core functionality doesn't really apply to what I'm doing. I tried to keep the question general and not specifically relating to desktop gadgets, so that this question would be useful for others.
Simple answer to your question: write your library using an existing one.
I have some javascript files written in jQuery just for such purposes.
More specifically,
If you are going for java-style object oriented-ness, go for namespaces. I prefer the jquery way of writing plugins.
If you are writing your own "toolkit", it would be best to copy and paste the dependencies (minified) into your source code. This way
a. you avoid the overhead you mentioned
b. you prevent unnecessary dependencies creeping up externally.
Cheers!
Concerning your first question, the two options are really the same IMO. Instead of a global object like YAHOO or gui, you have a global function like $. In both cases you have a global variable that holds your namespace.
Is there any reason why you can't use one of the many libraries out there already? This seems like a case of reinventing the wheel. These libraries have been around for years and have already tackled many of the issues that you will surely run into when trying to write your own.
In terms of some of your questions:
This is really a matter of preference IMO. As long as you get your functions out of the global namespace that is the major thing. However, this design choice will drive many others down the line.
It is best to include all core functionality in one file and then to chunk the rest into files that are required for a bit of functionality. You want to keep the number of files down, but you also don't want the user to have to download a lot of stuff that they don't need.
Having said all that, I restate that you should look at using one of the libraries already out there unless you have a very good reason not to. Keep in mind that you will need to test in all old browsers as well as any new browsers that come out.
jQuery, YUI, Prototype, Mootools, extJS are a few of the most popular
Related
I have been a user of jQuery (and some of its minor plugins) for a while. The Javascript code I've developed over the years could be described best as... messy. It used a ton of global variables and functions here and there, didn't use standard ways of organizing the code, nor any design patterns whatsoever.
I am currently building the new version of a website, and I have completed doing the backend with PEAR::MDB2 and Smarty templates. The rest is just homebrew PHP with some classes.
Now I am at the point where I'll add the Javascript layer on top of the website to improve the user-friendliness of some features. (while making sure everything degrades gracefully) I want to write better, cleaner, more organized Javascript than I used to, so I did a little research. I read Stefanov's Object-Oriented Javascript to have a better grasp on some concepts I knew only loosely about (prototypes, constructors, etc.) as well. Now I'm stuck at a point where I wonder which Javascript frameworks I should use, and how to organize it all.
After conducting my research, I understood Cappuccino & Objective-J, and Sproutcore were not what I was looking for. To quote Cappucino's about page:
Cappuccino is not designed for building web sites, or making existing sites more "dynamic". We think these goals are too far removed from those of application development to be served well by a single framework. Projects like Prototype and jQuery are excellent at those tasks
So there's that. Then I found out about Coffee Script, which is more of a one-to-one "compiler" and wouldn't help me with the actual organization of my code.
I also stumbled on some articles that give guidelines:
Using Inheritance Patterns to Organize Large jQuery Applications
A JavaScript Module Pattern
I also found out about Backbone.js, Shoestring, JavaScriptMVC, Google Loader, jQuery Tools, jQuery UI. I don't really know what to do of all this... The things I know:
I don't want to invest too much time in learning something too complex, I want to keep things simple and flexible as much as possible (that is why I don't use Symfony on the backend, for example), yet clean and organized.
I want to use jQuery, the question is, what should I use with it? (that is compatible too)
Right now, I'd use jQuery and jQuery Tools and "organize" all that in a simple namespace/object literal with simple properties and methods and also, since the site is localized, I just plan on using the simple vsprintf (as I do on the backend) with key:value pairs loaded from an object literal provided by the backend. JavaScriptMVC seems interesting, but I fear it would bring way too much complexity for a project that is fairly small sized. That is where I need your advice! Thank you very much in advance.
Ok, my attempt at an answer:
There is no 'best' to way to do it. You now know what's there and I think you might have a preference for yourself for what you want. In that case, pick a framework and learn it inside-out. (sorry to burst your bubble, but each framework has a learning curve, some steep, some very easy, but in the end to use it well you have to invest in it. Just do it, you won't be sorry).
You of course have an preference for clean code, so you might take some considerations into account. You also say you have a preference for jQuery, which is fine, but there are some limitations (as also pointed out in the link provided by eskimoblood).
There are some nice lectures / and tutorials with advice on how to structure your code in jQuery:
How to manage large jquery apps
On Large jQuery apps
Essential Javascript and jQuery patterns (free ebook)
Some style guides:
Jquery core UI Styleguide
Google Closure Javascript Style Guide
Tools for checking your code
JSLint
JSHint (a more forgiving/practical fork)
Closure Linter (haven't tried it yet, but intend to)
Standard works (javascript)
Everything by Douglas Crockford
Quirksmode
There might be more.. perhaps more people can contribute, but I also think that you've almost reached the end of what you can learn before getting your hands dirty. Many of these guides are written in a very generic way, but the interesting thing is that javascript is called upon in many specific situations. It might be useful to just post some of the code that you regard as "messy" and we can help you figure out how to do it better. Good luck!
You should watch the video and read the links in this article and then you should ask yourself again if jquery is the right tool. Maybe you will use dojo, that is much better for larger projects or you take a look at backbone and where you can stay with jquery. After all both of them are more "javascriptish" then something like sproutcore, cappuciono or even GWT. And also much easier to understand when you come from jquery.
One framework that is to consider is definitely ReactJS from Facebook. This framework is pretty slick in many ways.
First thing you have to know is that it is a view framework. It can be used server-side to do the pre-rendering of pages, but it really shines on client side. Since it's a view framework, it can be used with backbone or any other "back-front"-end framework.
One of the main point of React is its rapidity. It keeps a virtual DOM in memory and virtualize all the webpages events. So the virtuals event are used to keep events browser agnostics.
The virtual DOM kind of make programming a dynamic site as if you were programming an old static website. You can just shoot the whole HTML to render to the view engine (as if you were "re-rendering" the whole page) and it will manage the DOM operations. It does a diff between the new virtual DOM and the current virtual DOM and only inserts nodes that needs to be inserted. This way you reduce the number of DOM ops and thus increase your render speed by a lot.
A good place to start is this tutorial which shows how to use "Flux" (the web flow designed by Facebook for its site) in order to realize a Todo application!
Coming from Java, I'm wondering if a Java best practice applies to JavaScript.
In Java, there's a separation of interface and implementation, and mixing them up is considered a bad practice. By the same token, it is recommended to hide implementation details of your library from end developers.
For example, log4J is one of the most popular logging libraries out there but it is recommended to write code to the slf4j library or the Commons Logging library that "wraps" log4j. This way, if you choose to switch to another logging framework such as logback, you can do so without changing your code. Another reason is that you, as a user of a logging library, how logging is done is none of your concern, as long as you know what logging does.
So back to JavaScript, most non-trivial web applications have their own custom JavaScript libraries, many of which use open source libraries such as jQuery and dojo. If a custom library depends on, say jQuery, not as an extension, but as implementation, do you see the need to add another layer that wraps jQuery and makes it transparent to the rest of JavaScript code?
For example, if you have the foo library that contains all your custom, front-end logic, you'd introduce the bar library that just wraps jQuery. This way, your foo library would use the bar library for jQuery functions, but it is totally oblivious to jQuery. In theory, you could switch to other libraries such as dojo and google web toolkit without having a big impact on the foo library.
Do you see any practical value in this? Overkill?
Although it makes sense from a theoretical standpoint, in practice I'd say it's overkill. If nothing else for these two reasons:
Anything that adds to the size of
the request (or adds more requests)
is bad - in web world, less is more.
If you're using say jQuery, the
chances of you switching to
something like Mootools is (imho) slim to none. From what I've seen, the top libraries each aim to solve different problems (at least in the case of Mootools and jQuery - see this great doc for more info on that). I'd assume that you'd incur a tremendous amount of headache if you were to try to implement a middleware library that could easily switch between the two.
In my experience and being a Java developer myself, sometimes we tend to take the whole "abstraction" layer pattern too far, I've seen implementations where someone decided to completely abstract a certain framework just for the sake of "flexibility" but it ends up making things more complicated and creating more code to maintain.
Bottom line is you should look at it on a case by case basis, for example you wouldn't try to create an abstraction layer on top of struts, or on top of JPA, just in case you then go to a different framework (which I've rarely seen done).
My suggestion is, regardless of the framework you are using, create objects and components that use the framework internally, they should model your problem and be able to interact between them without the need of any specific framework.
Hope this helps.
There are a lot of good answers here, but one thing I don't see mentioned is feature sets. If you try to write a library to wrap the functionality provided by, say, jQuery, but you want to be able to easily swap out for something like prototype, you have a problem. The jQuery library doesn't provide all the features prototype provides, and prototype doesn't provide all the features jQuery provides. On top of that, they both provide their features in radically different ways (prototype extends base objects -- that's damn near impossible to wrap).
In the end, if you tried to wrap these libraries in some code that adds 'abstraction' to try to make them more flexible, you're going to lose 80% of what the frameworks provided. You'll lose the fancy interfaces they provide (jQuery provides an awesome $('selector') function, prototype extends base objects), and you'll also have to decide if you want to leave out features. If a given feature is not provided by both frameworks, you have to either ditch it or reimplement it for the other framework. This is a big can of worms.
The whole problem stems from the fact that Java is a very inflexible language. A library provides functionality, and that's it. In JavaScript, the language itself is insanely flexible, and lets you do lots of crazy things (like writing a library, and assigning it to the $ variable). The ability to do crazy things lets developers of javascript libraries provide some really creative functionality, but it means you can't just find commonalities in libraries and write an abstraction. I think writing javascript well requires a significant change in perspective for a Java developer.
Someone wise once said "premature optimization is the root of all evil." I believe that applies in this case.
As others have expressed, you don't want to abstract for the sake of flexibility until you have an actual need for the abstraction. Otherwise you end up doing more work than necessary, and introducing unnecessary complexity before it is required. This costs money and actually makes your code more brittle.
Also, if your code is well organized and well tested, you should not be afraid of major changes. Code is always changing, and trying to anticipate and optimize for a change that may or may not come will almost always get you in more trouble than it saves you.
Acknowledgement: I should give credit to Agile programming and my practice and readings on the topic. What I've said comes directly from my understanding of Agile, and I've found it to be an extremely good razor to cut out the extra fat of my work and get lots done. Also none of what I've said is actually JavaScript specific... I'd apply those principles in any language.
There are good arguments calling this development practice - wrapping in order to switch later - into question in any language.
A good quote by Oren Eini, from his writeup on wrapping ORMs:
Trying to encapsulate to make things
easier to work with, great. Trying to
encapsulate so that you can switch
OR/Ms? Won’t work, will be costly and
painful.
This is definitely something that is done in enterprise environments.
Take for example a company that has their own custom javascript framework that is used on all of their projects. Each of the projects decide to use their own framework (jQuery, Dojo, Prototype) to add functionality to the underlying modules of the company framework. Employees that move between projects can now easily do so because their API with working the project's codebase is still the same, even though the underlying implementation could be different for each project. Abstraction is helpful in these situations.
It is overkill. Javascript is not Java and is not in any way related to Java. It is a completely different language that got J-a-v-a in the name for marketing reasons.
If you are concerned with availability of add-on libraries, then choose a framework with a large ecosystem. In an enterprise environment you will be further ahead by standardising on a vanilla off-the-shelf uncustomised web framework that you can upgrade every year or so tracking the rest of the world. And then supplement that with a SMALL in-house add-on library which you will, of course, have to maintain yourself, not to mention training any new programmers that you hire.
Since you are talking about Javascript in the client (web browser) it is more important that you limit the complexity of the things that people do with it. Don't build huge amounts of client side code, and don't make stuff that is so brittle that another programmer can't maintain it. A web framework helps you both keep the linecount down, and keep your own code reasonably simple.
It is not a question of Javascript best practice, because that would be different for server-side JS such as Rhino or node.js.
Adapter pattern is not a common solution in this case. The only example I know to use this pattern is extjs. Javascript projects are usually too small and they aren't worth the effort you would make by creating such an abstraction layer.
The common solution for this problem is that you try to use multiple frameworks together for example with jquery.noConflict.
I've done this before, and can talk a bit about the experience of writing a library/toolkit wrapper.
The plan was to move from Prototype to some other library. Dojo was the first choice, but at the time I wasn't sure whether that's the library to move everything to (and by everything I mean ~5MB of Prototype-happy JS). So coming from a world of clean interfaces, I was set to write one around Prototype and Dojo; an awesome interface that would make switching out from dojo a breeze, if that was in fact necessary.
That was a mistake that cost a lot of time and effort for a few reasons. The first one is that although two libraries can provide the same functionality, (a) their API will almost always be different, and most importantly (b) the way you program with one library will be different.
To demonstrate, let's take something as common as adding a class-name:
// Prototype
$("target").addClassName('highlighted');
// Dojo
dojo.addClass("target", "highlighted");
// jQuery
$("target").addClass("highlighted");
// MooTools
$('target').set('class', 'highlighted');
Pretty straight-forward so far. Let's complicate it a bit:
// Prototype
Element.addClassName('target', 'highlighted selected');
// Dojo
dojo.addClass("target", ["highlighted", "selected"]);
// jQuery
$("target").addClass(function() {
return 'highlighted selected';
});
// MooTools
$("target").set({
"class": "highlighted selected"
});
Now after choosing an interface for your version of the addClass you have two options: (1) code to the lowest common denominator, or (2) implement all of the non-intersecting features of the libraries.
If you go with the 1st -- you'll loose the "personality" / best qualities of each of the library. If you go with #2 -- your addClass' code will be at 4 times larger than the ones provided by any of the libraries, since for example when Dojo is included, you'll have to write the code for the function as the first param (jQuery) and the Object as the first param (MooTools).
Therefore, although it is theoretically possible, it isn't practical, but is a very nice way to understand the intricacies of the libraries out there.
I have developed one of my modules using Dojo. Its gone really well and I have done a lot of custom plugins and server support in Dojo to allow AJAX calls, RPC + SMD communication with my server.
However, now that I am getting onto the user side of things, I am seeing that jQuery has some really nice already built plugins. Do you think it is possible to support both JS libraries realistically without it being a massive problem?
What kind of integration can I achieve? Does anyone have experience in this?
I have probably written somewhere in the region of 30k lines in Dojo for my Administration panel...
jQuery is very good about not messing with the prototypes of built in javascript objects (unlike Prototype), this allows it to be used with other libraries quite easily.
A source of potential conflict is jQuery's use of $ as a shortcut for jQuery. I'm not a dojo user, but if this conflicts with dojo in some way, there are instructions addressing this.
That said, I think you'd be better off looking at these jquery plugins and rewriting them and porting them to dojo. I'm sure the dojo community would appreciate it, and it would give you experience. It'd also make your application a little slimmer in the waist area.
Edit: I've noticed a couple answers trivializing the download speed of adding an additional library. I'd take this with a grain of salt.
As developers we tend to see only the extra 10ms it takes to download the library over localhost, or from our development server on a 100 Mbit LAN. The download speed is not so trivial from California to Virginia, or especially from USA to Europe. Additionally, it adds further burden on your client's javascript engine. If they are using a 1-2 year old good computer with Safari or Chrome, this would be negligible, but if they're on IE, FF2, or some versions of FF3 the difference can be severe, or at least measurable.
When using 2 libraries (both of which, I'm sure - were designed to be used by themselves) you have 2 main worries:
That one library will effect the other.
That having a dependency on 2 libraries will bloat your pages.
In this case, I would bet that #1 is not going to happen. Although #2 is still a concern.
Most of the popular JS libraries can be scoped to their own global shortcuts. JQuery can be set to not initialize the $ variable. JQuery aside, I hear that Dojo and Prototype can work together without conflicting.
Regardless of what combination of JS libraries you decide to use, the best way to get information on compatibility issues is to hit the mailing lists relevant to the JS libs you'll be using with each other.
http://docs.jquery.com/Using_jQuery_with_Other_Libraries
http://www.dev411.com/blog/2006/06/13/dojo-and-prototype-together
Query.noConflict() makes for fairly easy interoperability because you can redefine $. As hobodave draws attention to, Prototype is lousy in this regard (because you can't easily just redefine $ with Prototype). I am not sure but I think Dojo doesn't have any issues of it's own and plays nicely with others out of the box (please someone correct me if that's not true).
The biggest problem I've had is the number of "must have" libraries written in specific frameworks, such as for things like sophisticated graphing that would be non-trivial to implement from scratch.
Bloat is bad, but compared to image sizes JS script sizes are of negligible concern (because it's so small and connections are so fast and it's only on first page load if you get your caching right, it's almost a non issue). I'd say maintiainablity being more of a worry, and it's a matter of deciding if you want that must-have-plugin that you don't have the time or inclination to reinvent in whatever framework you are using.
I have used Prototype, jQuery, and ExtJS on several projects (for various reasons) and almost always use jQuery and ExtJS together. One way to limit trouble would be to avoid mixing libraries in any given page - keep Admin page to dojo and new pages to jQuery - but what fun would that be? :-)
I find few problems when integrating jQuery and ExtJS. I pick a framework for classes/objects/inheritance (I use ExtJS) and stick to it. Then, I use ExtJS to create most widgets and I use jQuery for low-level DOM manipulation and simple widgets. Again, I cannot recall running into conflicts when using two libraries, but FireBug is a good tool to uncover suspected causes of such conflicts.
We started a new project and realized that we needed a general purpose javascript library that contains a nice set of string functions, MD5, base64, allows extensions, etc. Also, copying and pasting functions from other libraries doesn't sound very attractive.
So, I guess the question is which javascript library contains the most general purpose functionality out there? or maybe there is a good collection of global functions out there we could use/extend. We know DOM manipulation is covered by many AJAX libraries including JQuery.
*Mind you, we could alternatively extend ExtJS, JQuery, etc. Is that what you guys are doing?
Google Closure Library
It contains (quoted from link):
a large set of reusable UI widgets and controls, and from lower-level utilities for DOM manipulation, server communication, animation, data structures, unit testing, rich-text editing, and more.
It also contains a nice set of string manipulating methods, in goog.string namespace.
Underscore
Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support that you would expect in Prototype.js
Underscore is intended to go along with other library, like jQuery or prototype.
It's not extensible like jQuery or Google Closure, though.
*Mind you, we could alternatively extend ExtJS, JQuery, etc. Is that what you guys are doing?
Yes, I do and I think most are. A lot of what you describe as a "general purpose library" is covered by Frameworks like JQuery, Prototype or Moo. And short of clipping the webmaster's nails, there's a JQuery plugin for everything that's not already in the core.
Still, I'm interested to see whether any other "general purpose" libraries come up here. There are fields - like string manipulation, as stated in one of the comments to another answer, and advanced date operations - where none of these frameworks is the holy grail AFAIK.
I use the jQuery library and a bunch of plugins. jQuery's plugin directory contains a lot of useful tools. There's also jQuery UI, a set of interactive components and effects, which you can use if you don't want to use a more complex library like ExtJS.
Of course every project is different, and you will probably end up writing some helper functions on your own.
I realize that others are going to say the same, but jQuery truly amazes me every time I learn something new about it.
DOM, CSS, and event manipulation along with easy AJAX, extensibility, and the plethora of existing extensions make jQuery a wonderful tool for web development.
jQuery is incredibly useful for UI manipulation. However, being open source, it contains some less than optimal code. If you start running into performance issues, don't be afraid to delve into the source and see what's going on.
I have been using jQuery for some time now and that seems to handle most of the basic operations I need. It has a healthy library of plug-ins and you can always write your own. It is a very good lightweight js library and even if it doesn't do all that you need it to you it is a good starting point.
I've been doing a lot of reading about AJAX, and wanted to know which is the better way to approach things: by using a library such as jQuery using their built-in methods or creating JavaScript without a library for AJAX?
Ajax has a lot of quirks when working with the XMLHttpRequest Object. When you start to work with it, you will not see it, but when it is out in a production environment, it will bite you in the butt. Browsers, browser version, user settings, the type of server, type of request, and much more can affect what needs to be coded. Libraries tend to solve most of the problems, but they all are not perfect.
I always tell people it is great to work with a tutorial to see how the XMLHttpRequest works. After you have learned how to do it naked, work with a library that fits your needs.
Eric Pascarello
Why create a library when plenty already exists? If you create a library it is going to take time and effort and you'll end up going through the same hurdles others already have. And unless your company is trying to sell an Ajax library then stay away from writting your own plumbing code.
I am currently using both JQuery and Microsoft's Ajax in my site and have found that they are both feature complete with plenty of options of different ways you can set up the communication.
If you ask this question on comp.lang.javascript you'll get lots of different answers, many of which disdain the commonly-used libraries (one quote sometimes taken slightly out of context is Richard Cornford's post on c.l.js in 2007: "Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not the
best source of advice on designing systems that use javascript.")
The argument for libraries is they abstract away most of the differences between browsers and allow for cross-browser scripting. The argument against libraries is that they are bloated code with quirks of their own, so you'd have to learn just as much to use them well as you would to use cross-browser techniques in raw javascript. If you are writing lots of Javascript that you're going to reuse in multiple places, and you're trying to make websites that load quickly and use a minimum of excess bandwidth (e.g. if you have pay-per-use webhosting like via Amazon S3 or nearlyfreespeech.net), then it's probably worth stripping whatever you're going to use out of a good library, tweaking it, and using that.
I was all psyched about Prototype for a while, but then decided I just need a few simple building blocks. I tend to use Doug Crockford's simple JSON library, and then some of Fork Javascript's minimalist libraries as needed (primarily FORK.Ajax), and do the rest myself from scratch or reusing routines from an earlier project that I've honed to something that works well for me.
why wouldn't you use library if it meets your needs. you're using .net framework, or java JRE, or php built-in functions...
you can create your own javascript for the purpose of learning, or to do something libraries don't offer. but for regular development, you are much quicker with library and you get cross-browser compatible JS without having to code cross-browser support manually, it's already built-in into the library