【问题标题】:require.js modules not loading properlyrequire.js 模块未正确加载
【发布时间】:2012-03-20 13:59:23
【问题描述】:

我有我的引导文件,它定义了 require.js 路径,并加载了应用程序和配置模块。

// 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', 代码。
  • 如何检查是否声明了多个版本的define?另外,我尝试过使用和不使用“app”声明
  • 不敢说实话!但是如果有两个相互竞争的定义函数,那么模块的状态可能是不确定的,即使它们看起来正在工作(即执行传递给定义的“工厂”函数)。您可以尝试将您的应用程序剥离到最简单的部分并逐渐添加依赖项吗?
  • 我已经剥离了它的所有依赖项,但它仍然没有通过
  • 我无法使用您问题中的代码生成相同的错误...您可以提供更多信息吗?可以重现错误的页面是一个好的开始...

标签: javascript requirejs


【解决方案1】:

据我所知,您可能应该在 app.js 定义方法中删除“app”字符串。

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

【讨论】:

  • 删除应用程序字符串会起作用。这种模式对我有用:'require(["app"], function(App) { App.initialize(); });' app.js 写成 define(['jquery'], function($){ function initialize() {}; return { initialize: initialize }; });
  • 使用应用字符串时,您定义的模块应该返回对库的引用。像 jQuery 这样的库会将自己定义为:'define( "jquery", [], function () { return jQuery; } );'
【解决方案2】:

好的,我遇到了同样的问题,关键是您定义的 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。这有助于避免不受欢迎的魔法行为。

original tutorial 我读到他们使用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>
    

    【讨论】:

      【解决方案4】:

      这就是我使用 requirejs 和主干的方式:

      首先,使用 config 定义主文件或引导文件:

      // 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 () {
                              /* .... */
              }
          });
      });
      

      希望对你有帮助!

      【讨论】:

        【解决方案5】:

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

        我出于不同的原因发布了这个问题,首先要问为什么我的修复工作有效。 Elclanrs 提供了完美的答案。长话短说,未定义可能是由于 javascript 的自动分号插入而出现的:Automatic semicolon insertion & return statements

        如果您尝试将大括号的位置从下方更改为直接在 return 语句之后,我认为您的问题将消失。

        // Filename: app.js
        define(
        .
        .
        .
        
            function($, _, Backbone){
                var initialize = function()
                {
                    //initialize code here
                }
                return {
                    initialize: initialize
                };
            }
        );
        

        【讨论】:

        • 大括号的位置没有任何影响。括号确实存在。
        • @Adrian 设计。对我投反对票然后留下错误信息的评论真是令人作呕。在误导未来的程序员之前,请注意语言的陷阱。 javascript 的自动分号插入功能立即结束 return 语句,而不是将代码包含在下一行的花括号中。应用程序的原始海报未定义。这就是原因。我什至在我的回答中说了这个,你有没有尝试阅读它?
        猜你喜欢
        • 2015-01-10
        • 2013-01-21
        • 2011-08-30
        • 1970-01-01
        • 1970-01-01
        • 2012-07-30
        • 2013-01-23
        • 1970-01-01
        • 2022-01-26
        相关资源
        最近更新 更多