I've written a full web app and I bootstrap it with require in this line at the end of my HTML document:
<script src="js/vendor/require-2.1.6.min.js" data-main="js/main.js"></script>
Inside main.js, I declare my app using the following two functions:
requirejs.config({
paths: {
'jquery': 'vendor/jquery-1.9.1.min',
'lodash': 'vendor/lodash-1.3.1.min',
'knockout': 'vendor/knockout-2.2.1.min',
'bootstrap': 'vendor/bootstrap-2.3.2.min'
},
shim: { 'bootstrap': { deps: ['jquery'] } }
});
requirejs(dependencies, function main(dependencies) { ... });
Now, I want to port my app as a jQuery plugin. As such, the end result I desire is to wrap my app in a jQuery fn,
(function($) { $.fn.myPlugin = function() { ... }; }(jQuery));
modularize the code to compile into a single js file (plugin-1.0.0.min.js), include the code in another project, with or without AMD, and load my app into a div using
$('#pluginDiv').myPlugin({ options: {} });
First, do I need to change the requirejs/requirejs.config functions to declares in order to package my app as a modular component? Or do I simply leave my app like this? What about the config?
Next, how do I expose my plugin to the jQuery which the plugin user will be using, e.g. the one declared in the global scope? Will this work if they're using an AMD?
UPDATE
For question 1, I moved my requirejs.config to a build file, build.js, which requires some additional properties:
({
baseUrl: ".",
paths: {
'jquery': 'vendor/jquery-1.9.1.min',
'lodash': 'vendor/lodash-1.3.1.min',
'knockout': 'vendor/knockout-2.2.1.min',
'bootstrap': 'vendor/bootstrap-2.3.2.min'
},
shim: { 'bootstrap': { deps: ['jquery'] } },
optimize: "none", // for debug
name: "main",
out: "plugin.js"
})
I was able to use r.js to compile this and it works great.
I am still stuck on question two, however. The code in my compiled myPlugin.js is as follows:
requirejs(dependencies, function main(dependencies) {
(function($) {
$.fn.myPlugin = function(options) {
...
return this;
};
})(jQuery);
});
where dependencies does not include jQuery. Then, I bootstrap the app by calling:
<script src="js/vendor/require-2.1.6.min.js" data-main="js/app.js"></script>
And the code in app.js is
requirejs.config({
paths: { 'jquery': 'vendor/jquery-1.9.1.min' },
shim: { 'myPlugin': ['jquery'] }
});
requirejs(['jquery','myPlugin'], function main($) {
$('#plugin').myPlugin(options);
});
However, my code always attempts to bind the plugin (from app.js), fails when the plugin is not a method on jQuery, and THEN loads the compiled plugin code and creates the method on jQuery. What's the problem here??
UPDATE 2
So, I've created a modular JavaScript file plugin.js using requirejs and its optimizer. The main code in the compiled plugin script,
requirejs(dependencies, function main(dependencies) {
(function($) {
$.fn.plugin = function(options) { return this; }
})(window.jQuery);
);
doesn't get called until after the main code in the parent app:
requirejs(['jquery','plugin'], function main($) {
$('#plugin').plugin({});
});
I assume this is because they are both making calls to requirejs. So the problem here is how to write my plugin such that it is usable within an AMD loader.
Sorry, I'm still figuring out the right questions to ask.