Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have recently started using require.js (along with Backbone.js, jQuery, and a handful of other JavaScript libs) and I love the module pattern (here's a nice synopsis if you're unfamiliar: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth). Something I'm running up against is best practices on incorporating libs that don't (out of the box) support the module pattern. For example, jQuery without modification is going to load into a global jQuery variable and that's that. Require.js recognizes this and provides an example project for download with a (slightly) modified version of jQuery to incorporate with a require.js project.

This goes against everything I've ever learned about using external libs - never modify the source. I can list a ton of reasons. Regardless, this is not an approach I'm comfortable with.

I have been using a mixed approach - wherein I build/load the "traditional" JS libraries in a "traditional" way (available in the global namespace) and then using the module pattern for all of my application code. This seems okay to me, but it bugs me because one of the real beauties of the module pattern (no globals) is getting perverted.

Anyone else got a better solution to this problem?

share|improve this question
    
This is why people maintain commonJS compliant forks of popular open source libraries through the NPM. –  Raynos Apr 14 '12 at 6:19
    
@Raynos - I fear upkeep on such maintenance for the same reasons I fear having an onerous process to updating an integration codebase myself - keeping up with current lib releases. Forking for functional differences makes sense to me, but unless the code originators are going to publish into a commonJS compliant format themselves, I'm disinclined to trust in the ongoing support of such - especially if I'm using a non-standard/out-of-vogue lib. –  webnesto Apr 14 '12 at 6:32
    
Additionally, this would only address the issue of the main lib in the case of something like jQuery - any plugins desired might not be compliant, and you're back to square one. –  webnesto Apr 14 '12 at 6:33
    
The main point it's trivial to automate commonJS / AMD compliance with a wrapper / build system. As for jQuery plugins, don't use them, all of them are shit –  Raynos Apr 14 '12 at 7:29
    
That's a good point (on the automation). May need to just go that route. Don't agree about the plugins. There are a number of solid great plugins. BBQ (benalman.com/projects/jquery-bbq-plugin) is well written and extremely useful. –  webnesto Apr 14 '12 at 16:20
show 1 more comment

2 Answers

up vote 1 down vote accepted

IMHO one of the most desirable features one could add to the html standard would be just that: loading a script without executing it right away*. I'd love to have all the code in a script wrapped in a closure, and call it like a function when and if I wanted (maybe even passing parameters to it, for instance using html attributes for that - but that is another story). That would solve many problems in programming for the browser today.

jQuery provides us with the noConflict utility, which is useful if you want to remove the global binding(s), but you have to call it "after the fact". I have no experience with require.js, so it's hard to say whether or not that would be a problem. But it's one of the best ways I know of keeping your programs global-free, and I tend to mimic in my own scripts.

Most jQuery plugins also abstain from creating globals, but they usually require that jQuery (and sometimes $, though it's a bad practice) exists as a global to work correctly - so it's better to use noConflict after all plugins are loaded (and some badly constructed ones might fail even then).

A "last resort" way I can think of accomplishing the same goal would be loading a script as text, using Ajax for instance, wrapping it into a closure before calling eval on it. Cumbersome, but not without its advantages (you could make checks/changes to the loaded script before actually running it - for instance if you load it from external sources). You'd lose some browser protections against XSS though...

About modifying the sources, I agree with MainMa, nothing wrong with that short of the specific pros/cons stated.

*Note: when I say "wrapping all code in a closure", I don't mean the way most scripts already do: create a function and then call it. I meant to create a function and allow another part of your program store it, executing it when convenient. AFAIK there's no "standards-compliant" way of doing that.

share|improve this answer
    
Based on your answer, you should really look into Require.js (requirejs.org), you'll probably like how the resulting code is structured/executed. –  webnesto Apr 14 '12 at 5:45
    
Thanks for coming up with a creative solution to the problem. Not sure I'll go the eval route, but you certainly answered the question. –  webnesto Apr 15 '12 at 1:54
add comment

There is (nearly) nothing wrong in modifying the external libraries. jQuery is an open source project, so if you can adapt it to your particular needs, just do it.

There might be some issues with this approach:

  • When a new version of jQuery is released, what is easier to do? Update the <script> tag of a website to use the new version, or waste your time reapplying the changes you've already done to the older version?

  • When using an official version of jQuery, you can benefit of Google CDN. If you have your own, modified version, you have to host it yourself.

  • If you're working with other people, they may not be familiar with your changes, and assume that you are using the original jQuery library.

All those issues are still minor in most circumstances. For example, unless you have a large scale web application, I'm not sure that it's the fact that you don't use Google CDN which will be the bottleneck.

So if you have enough experience to do it, there is nothing wrong in modifying the existent libraries in order to better fit your requirements.

share|improve this answer
    
It is, in fact the "new version" issue that has been disastrous to me in the past and why I avoid it wherever possible now. As this modification doesn't have a real impact on the API at all (and could probably be scripted so that I don't have to remember how I did it, but could automate it if necessary), your argument does sound convincing. –  webnesto Apr 14 '12 at 5:18
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.