我怎样才能在每个模块中绕过需要定义(['jquery'])?

时间:2016-04-22 19:32:37

标签: javascript jquery requirejs

我正在使用RequireJS,我有数百个模块。我希望每个模块都有一组基本的模块已经定义并准备就绪,而不必在每个模块中列出所有模块。

我想定义一个每个脚本使用的单个全局模块,它返回jQuery并包含我们需要的其他一些东西,比如jQuery验证器插件等。

以下是我的布局的简化版本。

js/app/Config.js
js/app/Global.js
js/app/util1.js
js/app/util2.js
js/app/foo.js
js/vendor/require.js
js/vendor/jquery.min.js
js/vendor/jquery.validator.js

在我的HTML中:

<script src="/js/app/Config.js"></script>
<script src="/js/vendor/require.js"></script>
<script>
    require('app/foo');
</script>

Config.js

var require = {
    baseUrl : '/js',
    paths : {
        'global' : 'app/Global',
        'jquery' : [ 'vendor/jquery.min' ],
        'jquery.form' : 'vendor/jquery.form',
        'jquery.validate' : 'app/_config/jquery.validate.custom',
        'jquery.validate.core' : 'vendor/jquery.validate',
        'jqueryui' : 'vendor/jquery-ui-1.10.4.custom.min',
        'underscore' : 'vendor/underscore'
    },
    shim : {
        'jquery.validate' : [ 'jquery.form', 'jquery.validate.core' ],
        'jquery.validate.core' : [ 'jquery' ],
        'underscore' : {
            exports : '_'
    }
};

Global.js

define([
    'jquery',
    'app/util1',
    'app/util2'
], function ($) {
    // all my custom global functions and code go here
    return $;
});

foo.js

define([
    'global'
], function ($) {
    'use strict';

    $('#foo').validate(); // $ is undefined here
});

我认为这会起作用,但它表示$在foo.js中未定义。不应该'foo'模块加载Global,它必须加载它在require数组中的所有模块,比如'util1'和'util2'?

1 个答案:

答案 0 :(得分:1)

尝试安装xrayquire,然后在控制台调试器中检查与xrayquire.showCycles();的循环依赖关系。

关于你的问题,我遇到了类似的问题,我发现自己编写了大量的require文件,但是我一直得到requirejs抛出的依赖加载错误。这看起来有些过分,但我的解决方案是创建接口(不是类类型,而是我自己的全局库)。

因此,假设我有一个名为[menu]的文件夹,其中包含大量需要文件,具有以下目录结构:

[app]
  interfaces.js
  [comms]
    IComms.js
    connect.js
  [menu]
    IMenu.js
    create.js
    [listener]
      onClick.js
      other files...

对于每个顶级目录,我创建一个接口文件,例如IMenu.js,这是我可以使用此接口文件调用方法的唯一方法。因此,如果我在comms目录中,我可以使用myapp.menu.create();调用方法,而不必担心循环依赖,也不会加载其他需要文件。

<强> IMenu.js

define(function(require) {
    var create = require('./create');
    var onClick = require('./listener/onClick');
    // load many other files here...

    function func() { 'this is private' };

    // exports
    return {
        'create'  : function()  { create(); },
        'onClick' : function(e) { return onClick(e); }
    };
});

<强> interfaces.js

define(function(require) {

    function setLocations() {
        window.myapp = {
            'comms' : require('comms/IComms'),
            'menu'  : require('menu/IMenu'),
            // load other app interface files...
        };
    };
    // exports
    return function(callback) { 
        setLocations();
        callback();
    };
});

<强> main.js

require.config({
    'paths' : { 
        jquery : '../libs/jquery',
        blah...
    }
});
// entry point
require(['interfaces'], function(interfaces) {
    interfaces(function() {
        // global `myapp` now fully loaded with interface files
        myapp.comms.connect();
        myapp.menu.create();    
    });
});

<强>摘要

main.js中,我调用interfaces文件,然后调用每个接口来构建应用程序。由于它通过回调,一旦完成,我可以调用任何接口,知道它存在于全局`myapp'变量上。

这是一个肮脏的黑客,但是当我使用xray时我得到零错误,它允许我将我的整个代码库封装在简单的调用之后,例如myapp.comms.addUser(),myapp.comms.disconnect(),myapp.menu.create()等..