Y U NO use libraries and add stuff

This is an early introduction to a project I have been thinking about for a while.
The project is already usable in github but the documentation is lacking all over the place so please be patient and I'll add everything necessary to understand and use yuno.

Zero Stress Namespace And Dependencies Resolver

Let's face the reality: today there is still no standard way to include dependencies in a script.
If we are using a generic JS loader, the aim is to simply download files and eventually wait for one or more dependency in order to be able to use everything we need.
The require logic introduced via node.js does not scale in the browser due synchronous nature of the method itself plus the sandbox not that easy to emulate in a browser environment.
The AMD concept is kinda OKish but once we load after dependencies, there is no way to implement a new one within the callback unless we are not exporting.
I find AMD approach surely the most convenient but still not the best one:
  1. we cannot implement a provide like procedure, whenever this could be handy or not
  2. it's not clear within the module code itself, what we are exporting exactly

Specially the last point means that AMD does not scale properly with already combined code because AMD relies in the module/folder structure itself ... so, cannot we do anything better than what we have so far?

The yuno Concept


Directly out of a well known meme, yuno logic is quite straightforward:
  • automagically resolved path, you point once to yuno.js file in your page and you are ready to go
  • compatible with already combined files (smart builder coming soon)
  • yuno.use() semantic method to define dependencies, if necessary
  • yuno.use().and() resolved callback to receive modules AMD style once everything has been loaded
  • yuno.add() standard ES5 way to define new namespaces, objects, properties, or constructors ( so no extra note in the documentation is needed )
  • cross referenced dependencies automagically resolved: if two different scripts needs same library, this will be loaded once for both
  • external url compatible, because you may want to include a file from some known CDN rather than put all scripts in your own host ( speed up common libraries download across different libraries that depend on same core, e.g/ jQuery )
  • modules, namespaces, or global objects, cannot be reassigned twice, which means if we are adding twice same thing we are doing it wrong, but if we are not aware of other script that added same thing before we have a notification
  • something else I may decide to add after this post
Here some example:

// define a jQuery plugin
yuno.use(
"jQuery",
"extraStuff"
).and(function (jQuery, extraStuff) {
yuno.add(jQuery.fn, "myPlugin", {value:function () {
// your amazing code here
}});
// we may opt for just this line
jQuery.fn.myPlugin = function () {};
// in order to export our plugin
// however, the purpose of yuno is to have
// a common recognizable way to understand
// what the module is about
// plus the "add" method is safer
});

Let's imagine that extraStuff contains similar code:

// define extraStuff
yuno.use(
"jQuery"
).and(function (jQuery) {
yuno.add(jQuery.fn, "extraStuff", {value:function () {
// your amazing code here
}});
});

Both plugin and extraStuff needs jQuery to be executed ... will jQuery be loaded twice? Nope, it's simply part of a queue of modules that needs to be resolved.
As soon as it's loaded/added once, every module that depends on jQuery will be notified so that if the list of dependencies is fully loaded, the callback passed to and will be executed.

Y U NO Add

Modules are only one part of the proposal since we may define a script where no external dependency is needed.

// note: no external dependency, just add
yuno.add(this, "MyFreakingCoolConstructor", {value:
function MyFreakingCoolConstructor() {
// freaking cool stuff here
}
});
// this points to the global object so that ...
MyFreakingCoolConstructor.prototype.doStuff = function () {
// freaking cool method
};

The yuno.add method reflects Object.defineProperty which means for ES5 compatible browsers getters, setters, and values, are all accepted and flagged as not enumerable, not writable, and not configurable by default.
Of course we can re-define this behavior but most likely this is what we need/want as default in any case ... isn't it?
For those browsers not there yet, the Object.defineProperty method is partially shimmed where __defineGetter/Setter__ or simply the value property will be used instead.
Bear in mind this shim may change accordingly with real needs but so far all mobile browsers should work as expected plus all Desktop browsers except IE less than 9 ... not so common targets for modern web sites.
Last, but not least, yuno logic does not necessarily need the add call so feel free to simply define your global object or your namespace the way you want.
However, as I have said before, the add method is a simple call able to make things more robust, to speedup and ensure notifications, and to use a standard, recognizable pattern, to define our own objects/functions being sure nobody did before thanks to defaults descriptor behavior which is not writable and not configurable indeed.

To DOs

This is just an initial idea of what the yuno object is able to do but few things are in my mind. On top of the list we have the possibility to shortener CDN calls via prefixes such "cdn:jQuery", as example, in order to use most common CDNs to load widely shared libraries.
Last, but not least, the reason I am writing this is because I am personally not that happy with any solution we have out there so if you are willing to contribute, please just leave a comment, thanks.

Comments

Popular posts from this blog

8 Things you should not be afraid of as a Developer

News

Why REST is so important