I have writted a Javascript plugin and I want to make it compatible with requireJS. However, I have some difficulties to make it work properly. I think my AMD is not correctly writted or something like this.
When I try to execute the plugin constructor it's not defined after requireJS have loaded the script ( the callback variable from requirejs is not defined also).
For example I use requirejs like this:
requirejs([
'./assets/js/myplugin.js'
], function( myplugin) {
console.log(myplugin); // undefined
new MyPlugin(); // undefined
});
And in myplugin.js I have this script:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(
'myplugin',
['brandname-util1/util1',
'brandname-util2/util2',
'brandname-util3/util3'],
factory
);
} else if (typeof exports === 'object' && module.exports) {
module.exports = factory(
root,
require('brandname-util1'),
require('brandname-util2'),
require('brandname-util3')
);
} else {
root.MyPlugin = factory(
root,
root.BrandNameUtil1,
root.BrandNameUtil2,
root.BrandNameUtil3
);
}
}(this, function factory(root, util1, util2, util3) {
'use strict';
var MyPlugin = function() {
}
return MyPlugin;
}));
The script is correctly loaded (Asynchronously) but nothing is defined. I'm not sure to fully understand how it works.
EDIT: here the utils scripts example:
// util1
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(
'brandname-util1/util1',
['jquery'],
factory
);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory(require('jquery'));
} else {
root.BrandNameUtil1 = factory(root);
}
}(this, function() {
"use strict";
var util1 = {};
// declare some functions
return util1;
}));
// util2
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define(
'brandname-util2/util2',
['jquery'],
factory
);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory(require('jquery'));
} else {
root.BrandNameUtil2 = factory(root);
}
}(typeof window !== "undefined" ? window : this, function() {
"use strict";
var util2 = function() {},
proto = util2.prototype;
// declare some proto
return util2;
}));
// util3
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(
'brandname-util3/util3',
['brandname-util1/util1',
'brandname-util2/util2'],
factory
);
} else if (typeof module === 'object' && module.exports) {
module.exports = factory(
root,
require('brandname-util1'),
require('brandname-util2')
);
} else {
root.BrandNameUtil3 = factory(
root,
root.BrandNameUtil1,
root.BrandNameUtil2
);
}
}(this, function (root, util1, util2) {
"use strict";
var util3 = function() {},
proto = util3.prototype;
// declare some proto
return util3;
}));
The only problem I see is that your factory takes root
as the first argument and then the modules. It works fine in the CommonJS (2nd branch) and no module system (3rd branch), but it fails in the AMD case (1st branch) because define
will call your factory with only 3 arguments: root
will be set to the first module of the dependency list, util3
won't be set, etc.
If you do not in fact use root
in your factory, you could just remove it from the parameter list and adjust the calls in the 2nd and 3rd branch to not pass it, and everything should work.
Otherwise, if you do need it in your factory, you could fix it by changing your first branch to do:
define(['brandname-util1/util1',
'brandname-util2/util2',
'brandname-util3/util3'],
factory.bind(undefined, root)
);
This sets the value of this
in the factory to be undefined
(which should be fine) and forces the first parameter in the factory to be set to the value root
has in the scope of your define
call. The modules are then appended after it.
See this documentation on bind for more details of how it works.
You should also not set a module name in your define
call. The call I show above removes the module name. The call should only have the dependency list and the factory.
And you should not put .js
in module names. So requirejs(['./assets/js/myplugin'],
without the .js
.