Requirejs:AMD模块未定义 [英] Requirejs: AMD Module not defined
问题描述
我想在我的模块中使用 datepickk.js :甚至想到了这个插件支持AMD,我无法在RequireJS中加载它: http://jsfiddle.net/numediaweb/5xbqqr0j/13/
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 {};
});
如果您检查控制台,您会看到定义了jquery,未定义模块.
If you check the console you will see that jquery is defined and the module not.
知道为什么会这样吗?
我尝试了加载此模块的另一种方式:
I tried another variation of loading this module:
require.config({
paths: {
'Datepickk': '//crsten.github.io/datepickk/dist/datepickk.min'
},
但随后出现此错误:
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)
推荐答案
谁为datepickk.js
编写了AMD代码,则需要阅读有关如何编写AMD模块的信息.有两个问题:
Whoever wrote the AMD code for datepickk.js
needs to read up on how to write AMD modules. There are two problems:
-
模块名称被硬编码为
Datepickk
,因为define
调用是define('Datepickk', Datepickk)
.第一个参数将硬编码该名称.这确实是一件坏事,因为RequireJS文档很清楚,开发人员不应该对名称进行硬编码,而应让优化程序根据需要添加名称,但是这里没有人注意.
The module name is hardcoded as
Datepickk
because thedefine
call 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.
这说明了为什么您的第二个配置(在paths
中带有Datepickk
的配置)有效,而您的第一个配置却无效.您必须在paths
配置中将其称为Datepickk
.如果您希望自己的代码将其引用为datepickk
,则除了paths
之外,还可以使用map
配置:
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"
}
}
是的,即使您解决了上述问题,您仍然会遇到遇到的错误.查看Datepickk
的文档,我发现您将其与do new Datepickk(...)
一起使用.如果执行此操作,则要冻结的对象应该是构造函数执行时由JavaScript虚拟机分配给this
的新对象.如果您查看使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;
第二和第三分支将Datepickk
构造函数导出到世界.没关系.不过,第一个分支对您很重要,它以Datepickk
作为模块工厂的方式调用define
.当RequireJS执行define
调用时,它立即调用Datepickk
来构建模块.在这种情况下,this
未被设置为任何特定值,因此它被设置为当前的Window
实例(JavaScript虚拟机执行此操作),并且Object.freeze
失败. define
调用应为:
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;
});
(我还删除了硬编码的模块名称.)这将构建一个具有功能的模块,该模块具有功能Datepickk
.
(I've also removed the hardcoded module name.) This builds a module that has for value the function Datepickk
.
这篇关于Requirejs:AMD模块未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!