Requirejs:未定义 AMD 模块
Requirejs: AMD Module not defined
我想在我的模块中使用 datepickk.js:即使我认为这个插件支持 AMD 我也无法在 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 已定义但模块未定义。
知道为什么会这样吗?
我尝试了加载此模块的另一种变体:
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 模块的信息。有两个问题:
模块名称被硬编码为 Datepickk
因为 define
调用是 define('Datepickk', Datepickk)
. 第一个参数硬编码名字。这确实是一件坏事,因为 RequireJS 文档明确指出开发人员不应硬编码名称,而是让优化器根据需要添加名称,但这里有人没有注意。
这解释了为什么您的第二个配置,即 paths
中带有 Datepickk
的配置有效,但您的第一个配置无效。您必须在 paths
配置中将其称为 Datepickk
。如果您希望自己的代码将其引用为 datepickk
,除了 paths
:
之外,您还可以使用 map
配置
map: {
"*": {
datepickk: "Datepickk"
}
}
是的,即使您修复了上述问题,您仍然会遇到 运行 遇到的错误。查看 Datepickk
的文档,我发现您将它与 do new Datepickk(...)
一起使用。如果这样做,那么被冻结的对象应该是构造函数执行时JavaScript虚拟机分配给this
的新对象。如果您查看使 Datepickk
可用于其他代码的代码,您会看到:
if ( typeof define === 'function' && define.amd ) define('Datepickk', Datepickk);
else if ( typeof exports === 'object' ) module.exports = Datepickk;
else window.Datepickk = Datepickk;
第二个和第三个 b运行ch 将 Datepickk
构造函数导出到世界。没关系。第一个 b运行ch 对你很重要, 调用 define
,Datepickk
充当模块工厂。当 RequireJS 执行 define
调用时,它 立即 调用 Datepickk
来构建模块。在这种情况下 this
未设置为任何特定值,因此它被设置为当前 Window
实例(JavaScript 虚拟机执行此操作)并且 Object.freeze
失败。 define
调用应该是:
define(function () {
return Datepickk;
});
(我还删除了硬编码的模块名称。)这构建了一个具有函数 Datepickk
.
值的模块
我想在我的模块中使用 datepickk.js:即使我认为这个插件支持 AMD 我也无法在 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 已定义但模块未定义。
知道为什么会这样吗?
我尝试了加载此模块的另一种变体:
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 模块的信息。有两个问题:
模块名称被硬编码为
Datepickk
因为define
调用是define('Datepickk', Datepickk)
. 第一个参数硬编码名字。这确实是一件坏事,因为 RequireJS 文档明确指出开发人员不应硬编码名称,而是让优化器根据需要添加名称,但这里有人没有注意。这解释了为什么您的第二个配置,即
之外,您还可以使用paths
中带有Datepickk
的配置有效,但您的第一个配置无效。您必须在paths
配置中将其称为Datepickk
。如果您希望自己的代码将其引用为datepickk
,除了paths
:map
配置map: { "*": { datepickk: "Datepickk" } }
是的,即使您修复了上述问题,您仍然会遇到 运行 遇到的错误。查看
Datepickk
的文档,我发现您将它与 donew Datepickk(...)
一起使用。如果这样做,那么被冻结的对象应该是构造函数执行时JavaScript虚拟机分配给this
的新对象。如果您查看使Datepickk
可用于其他代码的代码,您会看到:if ( typeof define === 'function' && define.amd ) define('Datepickk', Datepickk); else if ( typeof exports === 'object' ) module.exports = Datepickk; else window.Datepickk = Datepickk;
第二个和第三个 b运行ch 将
Datepickk
构造函数导出到世界。没关系。第一个 b运行ch 对你很重要, 调用define
,Datepickk
充当模块工厂。当 RequireJS 执行define
调用时,它 立即 调用Datepickk
来构建模块。在这种情况下this
未设置为任何特定值,因此它被设置为当前Window
实例(JavaScript 虚拟机执行此操作)并且Object.freeze
失败。define
调用应该是:define(function () { return Datepickk; });
(我还删除了硬编码的模块名称。)这构建了一个具有函数
Datepickk
. 值的模块