问题
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)
回答1:
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
Datepickkbecause thedefinecall isdefine('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
Datepickkinpathsworks, but your first one does not. You must refer to it asDatepickkin yourpathsconfiguration. If you want your own code to refer to it asdatepickk, you can use amapconfiguration in addition topaths:map: { "*": { datepickk: "Datepickk" } }Yeah, even if you fix the above, you still get the error you ran into. Looking at the documentation for
DatepickkI see that you are use it with donew Datepickk(...). If you do this, then the object to be frozen should be the new object that is assigned tothisby the JavaScript virtual machine when the constructor executes. If you look at the code that makesDatepickkavailable 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
Datepickkconstructor to the world. That's fine. The 1st branch though, which is the one that matters to you, callsdefinewithDatepickkacting as a module factory. When RequireJS executes thedefinecall, it immediately callsDatepickkto build the module. In this situationthisis not set to any specific value, so it gets set to the currentWindowinstance (the JavaScript virtual machine does that) andObject.freezefails. Thedefinecall 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.
来源:https://stackoverflow.com/questions/44808397/requirejs-amd-module-not-defined