Reputation: 17010
I want to use datepickk.js inside my module: even thought this plugin supports AMD I couldn't load it inside RequireJS: http://jsfiddle.net/numediaweb/5xbqqr0j/13/
// Config Object
requirejs.config({
// Local Directory
baseUrl: "/js",
// Script Locations
paths: {
// Common Libraries
"jquery": "//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min",
"datepickk": "//crsten.github.io/datepickk/dist/datepickk.min"
}
});
// Check Dependencies
requirejs(['jquery', 'datepickk'], function ($, Datepickk) {
var loadedMods = require.s.contexts._.defined;
console.log(loadedMods);
$('#message').text('Loaded modules => '+JSON.stringify(loadedMods));
return {};
});
If you check the console you will see that jquery is defined and the module not.
Any idea why this happens?
I tried another variation of loading this module:
require.config({
paths: {
'Datepickk': '//crsten.github.io/datepickk/dist/datepickk.min'
},
But then I get this error:
datepickk.js:1146 Uncaught TypeError: Cannot freeze
at Function.freeze (<anonymous>)
at Datepickk (datepickk.js:1146)
at Object.execCb (require.js:1693)
at Module.check (require.js:881)
at Module.enable (require.js:1173)
at Module.init (require.js:786)
at callGetModule (require.js:1200)
at Object.completeLoad (require.js:1587)
at HTMLScriptElement.onScriptLoad (require.js:1714)
Upvotes: 1
Views: 1742
Reputation: 151380
Whoever wrote the AMD code for datepickk.js
needs to read up on how to write AMD modules. There are two problems:
The module name is hardcoded as Datepickk
because the define
call is define('Datepickk', Datepickk)
. The first argument hardcodes the name. This is really a bad thing to do, as the RequireJS documentation is clear that developers should not hardcode names and instead let the optimizer add a name as needed, but here someone was not paying attention.
This explains why your 2nd configuration, the one with Datepickk
in paths
works, but your first one does not. You must refer to it as Datepickk
in your paths
configuration. If you want your own code to refer to it as datepickk
, you can use a map
configuration in addition to paths
:
map: {
"*": {
datepickk: "Datepickk"
}
}
Yeah, even if you fix the above, you still get the error you ran into. Looking at the documentation for Datepickk
I see that you are use it with do new Datepickk(...)
. If you do this, then the object to be frozen should be the new object that is assigned to this
by the JavaScript virtual machine when the constructor executes. If you look at the code that makes Datepickk
available to other code, this is what you see:
if ( typeof define === 'function' && define.amd ) define('Datepickk', Datepickk);
else if ( typeof exports === 'object' ) module.exports = Datepickk;
else window.Datepickk = Datepickk;
The 2nd and 3rd branch export the Datepickk
constructor to the world. That's fine. The 1st branch though, which is the one that matters to you, calls define
with Datepickk
acting as a module factory. When RequireJS executes the define
call, it immediately calls Datepickk
to build the module. In this situation this
is not set to any specific value, so it gets set to the current Window
instance (the JavaScript virtual machine does that) and Object.freeze
fails. The define
call should be:
define(function () {
return Datepickk;
});
(I've also removed the hardcoded module name.) This builds a module that has for value the function Datepickk
.
Upvotes: 1