- Is there anything I need to avoid to prevent conflicts with other libraries?
Simple answer is maybe, depending on your situation.
Example
jQuery by default adds itself as jQuery
on the window
object as well as $
. While it is unlikely that another library is going to call itself jQuery
(more on that later), the $
global is actually quite a common shortcut.
What jQuery does is save the variables $
and jQuery
internally and on calling $.noConflict()
will restore the previous set variables. [Reference]
Here is one very simple way of programming this:
var jQuery = function(){ return 1; };
(function()
{
var _jQuery = jQuery;
jQuery = function()
{
return 2;
}
jQuery.noConflict = function()
{
jQuery = _jQuery;
}
})();
//Prints "2"
console.log(jQuery());
var jQuery2 = jQuery;
jQuery2.noConflict();
//Prints "1"
console.log(jQuery());
//Prints "2"
console.log(jQuery2());
My questions would be:
- Are you wanting to use a common global variable (eg.
$
)?
- What types of scenarios do you see with people working with your library?
If your SDK is going to use a common global variable and or you think people could be slinging a dozen different libraries while using your code, you may want to consider it. I will note that if you design your object/functions well enough, it shouldn't be hard to add such functionality as I showed above later in your project.
- How do I handle dependencies? Should I encapsulate them or let the user know they have to add it?
How many dependencies are you thinking they might need? Are the dependencies quite common (ie. jQuery)?
Personally, if there are one or two dependencies, I would just state it in docs for your SDK. There is no need for you to go out and keep a copy of your dependencies internally maintained and tested.
Most jQuery plugins require jQuery (obviously) but don't bundle it simply because they don't need to. Generally these plugins state a minimum version of jQuery they support/have tested but not much beyond that.
While saying this, bundling can be useful especially if the API of your dependency isn't very stable. There is one library I have used called Kalendae which bundles Moment.js. In this case, I have found it being bundled quite useful.
There are downsides to bundling linking back to your first point, they can cause conflicts if the person is already including a particular version of XYZ library. If you do bundle, do it in a way to cause the least amount of annoyance for future developers.
Without knowing what your specific dependencies are, I can't really help you with whether under your case should you bundle or not.
- Are there any methods of structuring SDKs that provide similar benefits to, say, MVC within a web app?
I'm not exactly what you are asking here in relating SDK structure to MVC within a web app.
Depending what your SDK does and how people would likely integrate with it would explain how best to structure it.
In terms of general things to do:
- Keep the global variables down to a minimum. Possibly wrap your code in a closure to avoid doing this (depending how your lay out your code).
- Allow flexibility by allowing callbacks and events. Given you are doing a REST API, you might want to look into JS Promises. There are many libraries that provide such functionality and hopefully soon, browsers will provide this natively. [More info about futures/promises/delay in Computer Science]
- Allow easy configuration/options to be passed to your functions. While it can be useful to add 20 different functions onto your object that configure a bunch of settings, it is far easier to allow the user to dump a JS object into a constructor or other function to do it all at once.
If you can explain more about that 3rd point, I might be able to provide a better answer.
Note
I mentioned that another library wouldn't call itself jQuery
in the global space. While that would generally hold true, if the person is using two different versions of jQuery on the same page (believe me, it happens) then it would run into issues. By default, calling $.noConflict()
will only fix the $
reference in the global scope however $.noConflict
has an optional parameter for also doing the same thing to the jQuery
object.