require.js模块未能正确加载

10
我有一个引导文件,它定义了 require.js 的路径,并加载了 app 和 config 模块。
// Filename: bootstrap

// Require.js allows us to configure shortcut alias
// There usage will become more apparent futher along in the tutorial.
require.config({
    paths: {
        bfwd: 'com/bfwd',
        plugins: 'jquery/plugins',
        ui: 'jquery/ui',
        jquery: 'jquery/jquery.min',
        'jquery-ui': 'jquery/jquery-ui.min',
        backbone: 'core/backbone.min',
        underscore: 'core/underscore.min'
    }
});
console.log('loading bootstrap');
require([
    // Load our app module and pass it to our definition function
    'app',
    'config'
], function(App){
    // The "app" dependency is passed in as "App"
    // Again, the other dependencies passed in are not "AMD" therefore don't pass a parameter to this function
    console.log('initializing app');
    App.initialize();
});

app.js被正确加载,它的依赖项也被加载。它的定义回调被调用,并传递了所有正确的依赖项作为参数,没有错误抛出。然而,在引导程序的回调中,App未定义!没有传递任何参数。这可能是什么原因?以下是我的应用程序文件(已修改以节省空间)

// Filename: app.js
define(
    'app',
    [
        'jquery',
        'underscore',
        'backbone',
        'jquery-ui',
        'bfwd/core',
        'plugins/jquery.VistaProgressBar-0.6'
    ], 
    function($, _, Backbone){
        var initialize = function()
        {
            //initialize code here
        }
        return 
        {
            initialize: initialize
        };
    }
);

你能检查一下是否声明了多个 define 函数吗?此外,通常最好使用匿名定义。因此,也许可以从模块中删除 'app' 代码。 - Paul Grime
如何检查是否声明了多个版本的define?另外,我已经尝试过带有和不带有'app'声明的情况。 - LordZardeck
说实话我不确定!但是如果有两个竞争的define函数,那么模块的状态可能是不确定的,即使它们似乎在工作(即传递给define的“工厂”函数被执行)。你可以尝试将你的应用程序剥离到最基本的部分,然后逐渐添加依赖项吗? - Paul Grime
我已经剥离了所有依赖项,但它仍然无法通过。 - LordZardeck
我无法使用您问题中的代码生成相同的错误...您能提供更多信息吗?提供一个可以重现该错误的页面是一个好的开始... - Marcelo De Zen
5个回答

12
据我所知,您应该只需在app.js的define方法中删除'app'字符串。
// Filename: app.js
define([
    'jquery',
    'underscore',
    'backbone',
    'jquery-ui',
    'bfwd/core',
    'plugins/jquery.VistaProgressBar-0.6'
], function($, _, Backbone){
    ...
);

去掉'app'字符串应该可以正常工作。这个模式对我有用:'require(["app"], function(App) { App.initialize(); });',其中app.js被编写为define(['jquery'], function($){ function initialize() {}; return { initialize: initialize }; }); - widged
当使用应用程序字符串时,您定义的模块应返回对库的引用。像jQuery这样的库将定义自己为:'define(“jquery”,[],function(){return jQuery;});' - widged

5

好的,我遇到了同样的问题,关键在于你定义的jquery路径别名。事实证明,RequireJS对jquery有一些特殊处理。如果你使用jquery模块名称,它会在那里进行一些魔法。

根据你在jquery.min.js中拥有的内容,它可能会引起一些问题,还有你在那里拥有的jquery插件也可能是个问题。这里是RequireJS源代码中相关的代码行:

    if (fullName) {
        //If module already defined for context, or already loaded,
        //then leave. Also leave if jQuery is registering but it does
        //not match the desired version number in the config.
        if (fullName in defined || loaded[id] === true ||
            (fullName === "jquery" && config.jQuery &&
                config.jQuery !== callback().fn.jquery)) {
            return;
        }

        //Set specified/loaded here for modules that are also loaded
        //as part of a layer, where onScriptLoad is not fired
        //for those cases. Do this after the inline define and
        //dependency tracing is done.
        specified[id] = true;
        loaded[id] = true;

        //If module is jQuery set up delaying its dom ready listeners.
        if (fullName === "jquery" && callback) {
            jQueryCheck(callback());
        }
    }

我将其设置为一个名为 /libs/jquery/jquery.js 的文件,该文件返回 jquery 对象(只是 RequireJS 的包装器)。我最终所做的是将路径别名从 jquery 更改为 $jquery。这有助于避免不希望出现的魔法行为。
原始教程 中,我看到他们使用 jQuery 也可以正常工作。

3
这是一个简单的例子,可以帮助您入门:
我创建了一个非常简单的模块:

https://gist.github.com/c556b6c759b1a41dd99d

define([], function () {
  function my_alert (msg) {
    alert(msg);
  }
  return {
    "alert": my_alert
  };
});

我在这个代码片段中使用了它,只需要jQuery作为额外的依赖项:

http://jsfiddle.net/NjTgm/

<script src="http://requirejs.org/docs/release/1.0.7/minified/require.js"></script>
<script type="text/javascript">
  require.config({
    paths: {
        "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min",
        "app": "https://gist.github.com/raw/c556b6c759b1a41dd99d/20d0084c9e767835446b46072536103bd5aa8c6b/gistfile1.js"
    },
    waitSeconds: 40
  });
</script>

<div id="message">hello</div>

<script type="text/javascript">
  require( ["jquery", "app"],
    function ($, app) {
      alert($.fn.jquery + "\n" + $("#message").text());
      app.alert("hello from app");
    }
  );
</script>

1
这是我使用requirejs和backbone的方法:
首先,使用配置定义主文件或引导文件:
// bootstrap.js
require.config({
    paths: {
        text: 'lib/text',
        jQuery: 'lib/jquery-1.7.2.min',
        jqueryui: 'lib/jquery-ui-1.8.22.custom.min',
        Underscore: 'lib/underscore-1.3.3',
        Backbone: 'lib/backbone-0.9.2'
    },

    shim: {
        'Underscore': {
            exports: '_'
        },

        'jQuery': {
            exports: 'jQuery'
        },

        'jqueryui': {
            exports: 'jqueryui'
        },

        'Zepto': {
            exports: '$'
        },

        'Backbone': {
            deps: ['Underscore', 'Zepto'],
            exports: 'Backbone'
        }
});

define(function (require) {
    'use strict';

    var RootView = require('src/RootView');
    new RootView();
});

然后,我使用this syntax来加载我的脚本。我发现这比数组符号更容易,只需通过var声明定义我的依赖项。

// rootview.js
define(function (require) {

    'use strict';

    var $ = require('Zepto'),
    Backbone = require('Backbone'),
    LoginView = require('./LoginView'),
    ApplicationView = require('./ApplicationView'),
    jQuery = require('jQuery').noConflict();



    return Backbone.View.extend({

        // append the view to the already created container
        el: $('.application-container'),

        initialize: function () {
            /* .... */
        },

        render: function () {
                        /* .... */
        }
    });
});

希望能对您有所帮助!


-1

虽然有点晚了,但我刚遇到了这个问题。我的解决方案可以在这里找到: https://stackoverflow.com/questions/27644844/can-a-return-statement-be-broken-across-multiple-lines-in-javascript

我发布了那个问题是为了问为什么我的修复方法起作用。Elclanrs提供了完美的答案。长话短说,undefined可能是由于JavaScript的自动分号插入而出现的:Automatic semicolon insertion & return statements

如果你尝试将大括号的位置从return语句下面改为直接放在后面,我认为你的问题就会消失。

// Filename: app.js
define(
.
.
.

    function($, _, Backbone){
        var initialize = function()
        {
            //initialize code here
        }
        return {
            initialize: initialize
        };
    }
);

花括号的位置完全没有影响,而花括号的存在则有影响。 - Design by Adrian
@Adrian设计。令人讨厌的是,你们给我投反对票,然后留下错误信息的评论。在误导未来的程序员之前,请注意语言的陷阱。JavaScript的自动分号插入功能会立即结束返回语句,而不是将代码包含在下一行的花括号中。原始帖子的app变量返回undefined,这就是为什么。我甚至在我的答案中说过了,你们有没有试着读一下? - MingShun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接