Requirejs:AMD模块未定义 [英] Requirejs: AMD Module not defined

查看:147
本文介绍了Requirejs:AMD模块未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的模块中使用 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:

  1. 模块名称被硬编码为Datepickk,因为define调用是define('Datepickk', Datepickk).第一个参数将硬编码该名称.这确实是一件坏事,因为RequireJS文档很清楚,开发人员不应该对名称进行硬编码,而应让优化程序根据需要添加名称,但是这里没有人注意.

  1. 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.

这说明了为什么您的第二个配置(在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屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆