Paul,
Glad to see you had a chance to take a look... I was beginning to think there wasn't anyone around anymore... almost gave out the Ferris Bueller reference... lol... anyway..
So, the reason I went the way I did is because this is the way Mootools will be doing it when they finally release verison 1.5. (
https://github.com/mootools/mootools-core/issues/2102). Also, in the case of some modules there's no way to know in advance what plugins, adaptors, or other classes could be needed.
This method uses the CommonJS wrapper technique and besides not listing the dependencies in the call to define it pretty much works the way you would expect it. Outside of Jx (as if I'm using it in an app) I can do as you say:
require(['jx/button'], function(Button){
//button loads and is usable here
});
The only difference comes in writing a component of the lib itself. For a part of Jx itself you should use define and the CommonJS style:
define('jx/path/to/file', function(require, exports, module){
//inside here you assign the final class to module.exports which requirejs recognizes as the same as a return
//you also use require() - synchronous version - to get the parts you need as the requirejs library scans the code
//for require() calls and loads those for you.
});
If you look in the examples/require directory you should find a test.html file that illustrates the usage outside of the library. The only issue I've come up against at this point is any dynamic requires (ones passed in such as plugins or adaptors or those determined at run time) because those cause exceptions to be thrown at the moment. I'm also seeing some empty objects being passed in for the normal require calls. I'm still trying to figure these out.
I will admit that I'm considering the following changes:
1) switch back to the "normal" syntax but keep using define rather than require
2) For any plugins/adaptors we would require the developer to pre-load them through their require statement
I'm also looking at a possible fix for this without changing the above however it will require either using the asynchronous version of require() and delaying some processing until we know that the needed modules are loaded, or possibly coding a shim around require that would be called inside jx modules (jx.require globally or base.require in modules) that would check to see if the module is already loaded and if so just pass it back and if not, call require to load it and then block until it's returned (not ideal obviously).
In any case, you can use modules on the fly using require(). There are currently 2 ways to get the modules:
- Just load the dependency with the file path: Jx.Button would be 'jx/button'
- Use the jx require plugin. This allows you to do 'jx!Button.Flyout'. You simply lowercase the first jx (so require recognizes it) and exchange the first '.' with a '!' so require recognizes this as a plugin. Do the rest of the filename as you would in global mode and it should load up for you.
Also, the mootools dependencies would need to be loaded separately before require until 1.5 when they will be AMD compatible. I tried loading them using require and it just got messy. I'm willing to try again though if you like....
As for the r.js optimizer... it also works with CommonJS modules from what I understand but there is no way that I've been able to figure out to build the entire library all at once as r.js doesn't scan directories but rather starts with a single .js file and builds out the dependencies from there. The way I have it set up we can continue to use the build process we have established to build the "full" build which includes a global.js file that is the magic piece for making this version a global drop-in replacement without having to adjust much code and you can use r.js on your main application file to build a customized version without the stuff you don't need.
As for the templating part - I'll look at handlebars again and let you know what I think. As for the text plugin, it could be handy but I don't see a way to do the following:
1) change the directory based on loaded theme.
2) reload templates when the theme changes
Anyway, I realize I just wrote a small book and that this is a lot to digest. As always, I'm open to suggestions, modifications, or anything else.
Thanks,
Jon