requirejs config给出了ReferenceError:找不到变量$

时间:2016-02-26 00:24:07

标签: javascript requirejs

也许我从根本上误解了requirejs配置是如何工作的,但我认为我的配置下面使一些库全局,所以我可以在其他文件中使用它们,而只需要和定义我需要在单个脚本中使用的文件。但是我不能在我的应用程序代码中引用$(jQuery)而不会得到一个引用错误,表明它不是全局可访问的。我已将问题与以下简单示例隔离开来。

我的文件设置如下:

test
  |
  |-index.html
  |-TestApp.js
  |-MainApp.js
  |-lib
  |  |-require.js
  |  |-jquery.js
  |  |-loadash.js
  |  |-backbone.js
  |-css
     |-test.css

库文件版本是RequireJS 2.1.22,jQuery 2.0.3,Loadash 3.10.1和Backbone 1.2.1。我只是尝试设置我的环境,我正在采取的方法是将我的TestApp.js文件传递给require.js以加载所需的文件并在MainApp.js中引导应用程序代码。 index.html中的脚本如下:

<!DOCTYPE html>
<html>
  <head>
    <link rel='stylesheet' type='text/css' href='css/test.css'/>
  </head>
  <body>
      <div></div>
      <script src="./lib/require.js" type="text/javascript" data-main="./TestApp.js"></script>
  </body>
</html>

引用的css脚本文件只是确保div显示为橙色方块。见下文:

div {
    height: 100px;
    width: 100px;
    background-color: #FA6900;
    border-radius: 5px;
    }

它是index.html中的脚本行,然后通过将我的配置文件传递给requirejs来启动应用程序代码。这是作为data-main传递的TestApp.js。 TestApp.js在这里:

require.config({
    paths:  {
            'jquery':   'lib/jquery',
            'lodash':   'lib/lodash',
            'backbone': 'lib/backbone'
            },

    map:    {
            '*':    {
                    // Backbone requires underscore. This forces requireJS to load lodash instead:
                    'underscore':   'lodash'
                    }
            },

    shim:   {
            jquery:         {exports:   '$'},
            underscore:     {
                            deps:       ['jquery'],
                            exports:    '_'
                            },
            backbone:       {
                            deps:       ['underscore'],
                            exports:    'Backbone'
                            },

            TestApp:        {
                            deps:       ['backbone'],
                            exports:    'TestApp'
                            }
            }
    });

require(['MainApp'], function(MainApp) {
    MainApp.run();
    });

上面的文件引用了我想要使用的库文件的路径,然后重新映射loadash以在需要下划线时加载(我需要一些额外的loadash功能),然后我使用垫片来确保依赖性是正确加载文件。将此配置文件传递给index.html中的require.js似乎正在工作,因为所有文件都显示为在浏览器中加载。然而问题似乎是它们看起来并不像我想象的那样全球可用。

在config部分之后,最后一次require调用加载MainApp.js文件并调用公开的run函数。 MainApp.js看起来像这样:

define(function(require) {

    var run = function() {

                $(document).ready(function() {
                    $('div').click(function() {
                        $('div').fadeOut('slow');
                        });
                    });
                };

    return  {
            run:    run
            };
    });

据我所知,我不需要在require配置中提到我已经提到的文件,我认为它们应该加载并可用于此代码。这是我误解了正在发生的事情或错过了一步的地方。正在调用公开的run函数,但调用$的第一行会抛出错误:

ReferenceError: Can't find variable: $

所以我的问题是:

  • 我的想法出了什么问题?
  • (或)我做错了什么?
  • 我应该做些什么来预加载和提供 经常引用的库,所以我不需要和 在我拥有的每个文件中定义它们吗?

2 个答案:

答案 0 :(得分:0)

  

据我所知,我不需要在require配置中提到我已经提到的文件,我认为它们应该加载并可用于此代码。

你误解了RequireJS的工作原理。你应该从头到尾阅读documentation。现在,这是你应该改变的事情。

您的MainApp模块中应该define(function(require) { var $ = require("jquery");

shim

您应该移除jqueryunderscorebackbone所拥有的define,因为他们都致电shim并且define是仅适用于未调用TestApp的代码。我不知道shim是什么,但如果它是你自己的代码,你真的应该把它变成一个合适的AMD模块并删除{{1}}。

答案 1 :(得分:0)

@Louis让我意识到我上面所做的错误。更改TestApp.js中的垫片,使其显示为:

MainApp: {
         deps:       ['backbone'],
         exports:    'MainApp'
         }

更正了问题,现在Backbone,$和_都可用于我的应用程序代码的其余部分,而不会混淆每个文件所需的内容。即我不需要用以下内容开始每个文件:

define (['lib/jquery', 'lib/loadash', 'lib/backbone'], function($, _ , Backbone) {

在我的实际应用程序中,常见代表的列表非常大,这意味着我只需要定义本地使用的资源,并且可以从单个位置控制路径。