I am sure a lot of you have often wondered: why can't open-source javascript frameworks like dojo, YUI, jquery, prototype and the gazillion number of other alternatives work together? Why should I have to choose one framework over another when all I want is nice widget X from framework A and nice widget Y from framework B? How far apart are the frameworks and how complicated would it be to have some level of integration?
First off, lets remember that each framework is built according to certain interests and goals in mind. This is fine and each framework is expected to take their own approach to solving similar problems. What really frustrates me is the energy and time that goes in open-source javascript toolkits / frameworks (call them whatever you like) and the lack of interoperability, collaboration between these competing toolkits. There's any amazing amount of (free) time that is wasted developing "competing" widgets while that time could be spent developing open-source components that are re-usable for other toolkits.
Given the frustration, I finally decided to do something about it and looked at how most frameworks could be integrated.
The results of the first step can be seen here:
http://www.openmv.com/tests/dojo-ext-jquery.html
First Step?
The first step to me was clear, given the source of a javascript file, I needed to be able to figure out what this file needs to run successfully (its dependencies). After some research on a couple of frameworks, it appeared that Dojo had done a fair amount of good work in this area.
In dojo, each javascript file has a:
dojo.provide('dijit.layout.ContentPane')
dojo.require("dijit._Widget");
dojo.require("dojo.parser");
Mainly each javascript file declares what it provides (dojo.provide) and what it needs (dojo.require) -- its dependencies.
This sounds like a great start! But can we force other frameworks to use a dojo.require? Would this mean that a piece of the dojo base would be required in other frameworks? This doesn't seem at all ideal, especially if all you want to use is jquery. What we need is some sort "I play nice with other frameworks" interface.
Proposed Solution?
The WTI (Web Toolkit Interface).
http://www.openmv.com/tests/resources/js/wti.js
In short, by simply adding the following 5 lines to dojo:
if(typeof window.wti == "undefined") {
var wti = dojo;
var wti.require = dojo.require;
var wti.provide = dojo.provide;
}
The toolkit now says "Yes, I play nice other frameworks" (by implementing the WTI interface). So now that we have 1 framework thats taken care of, we also want jquery and Ext-JS to play nice.
We can do this by adding these 5 lines to jquery and Ext-JS:
if(typeof window.wti == "undefined") {
var wti = {};
wti.provide = function(resourceId) {};
wti.require = function(resourceId, /*optional*/resourceType) {};
}
That's it?! This is going to work? Not quite, each javascript file must then declare what it provides and what it requires:
For example:
wti.provide('jquery.interface.ifxscale');
wti.require('jquery.base');
wti.require('jquery.interface.ifx');
wti.require('jquery.interface.iutil');
Given these modifications, we now know enough information about each javascript files to integrate the frameworks / toolkits together. To give a small demo, I tweaked a little the dojo builder (to look for wti.require), and managed to compress jquery, Ext-js and dijit into 1 single file.
You can view the end result here
http://www.openmv.com/tests/dojo-ext-jquery.html
Basically this works:
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.layout.TabContainer");
// Load jquery animations
dojo.require('jquery.interface.ifxscale');
dojo.require('jquery.interface.ifxshake');
// Use jquery as $ selector
var $ = jQuery;
// Load Ext resources
dojo.require('Ext.ux.Accordion');
dojo.require('Ext.widgets.DatePicker');
dojo.require('Ext.widgets.layout.ContentPanels');
dojo.require('Ext.widgets.layout.BorderLayout');
I will of course be making all work available online, and contributing patches to dojo, jquery, Ext-js. This is a simple proposal that I hope will motivate some level of interoperability between javascript frameworks in one form or another.
Comments are very much welcome.
Step 2?
The next step will consist of modifying javascript files so they declare other types of media / resources they depend on, for example:
wti.provide('dijit.layout.ContentPane')
wti.require("dijit._Widget");
wti.require("dojo.parser");
wti.require("dijit.themes.dijit", '.css');