Browserify需要返回一个空对象

Ste*_*ams 23 javascript require backbone.js browserify

我有这个代码,由于我无法理解的原因,在使用时产生一个空对象require().我的文件结构是这样的:

src
|__ public
    |__ javascript
        |__ collections
            |   categories.js
            |   listings.js <-- Always an empty object
        |__ models
            |   category.js
            |   employer.js
            |   listing.js
            |   location.js
        |   routing
        |   templates
        |   tests
        |   ui-components
        |   views
Run Code Online (Sandbox Code Playgroud)

问题文件是collections/listings.js,在需要时似乎只是输出为空对象,如下所示:

var ListingsCollection = require('../collections/listings')

src/public/javascript/collections/listings.js 看起来像这样:

var $        = require('jquery'),
    _        = require('underscore'),
    Backbone = require('backbone'),
    Listing  = require('../models/listing');

Backbone.$ = $;

module.exports = Backbone.Collection.extend({
    url: '/listings',

    model: Listing,

    parse: function (response) {
        return response.listings;
    }
});
Run Code Online (Sandbox Code Playgroud)

这是一个出错的例子:

var $                  = require('jquery'),
    _                  = require('underscore'),
    Backbone           = require('backbone'),
    LocationModel      = require('../models/location'),
    ListingsCollection = require('../collections/listings');

Backbone.$ = $;

console.log(ListingsCollection); // > Object {}

module.exports = Backbone.Model.extend({

    urlRoot: '/employers',

    model: {
        location: LocationModel,
        listings: ListingsCollection
    },

    parse: function (response) {
        var employer = response.employer;

        // Create the child listings
        employer.listings = new ListingsCollection;

        return employer;
    },

    toJSON : function () {
        var json = _.clone(this.attributes);

        _.each(_.keys(this.model), function (child) {
            if (this.get(child)) {
                json[child] = this.get(child).toJSON();
            }
        }.bind(this));

        return json;
    }
});
Run Code Online (Sandbox Code Playgroud)

所以它就是 - 该集合永远不需要进入雇主模型,以便它可以用于为父模型创建子集合.我查看了这个来源并研究了这个问题,但到目前为止我还没有提出任何建议......这令人困惑.

mac*_*ost 21

由于我的评论似乎回答了这个问题,我以为我会正式写出来.

使用Require.js时,您必须考虑模块之间的依赖关系.从某种意义上说,这就像你没有使用require一样.让我们假装你有两个文件,A.js和B.js,它们分别定义了一个"A"函数和一个"B"函数:

// A.js
window.A = function() {
    // ...
};

// B.js
window.B = function() {
    // ...
};
Run Code Online (Sandbox Code Playgroud)

您可以按任意顺序将这些文件添加到您的页面,您的代码也可以使用.但是如果你对"B"的定义取决于"A"的定义怎么办:

// B.js
window.B = window.A || function() {
    // ...
};
Run Code Online (Sandbox Code Playgroud)

现在,突然命令很重要:你必须在你的A.js文件之后包含你的B.js文件,否则B的代码将无效.如果你的A.js也取决于你的B.js ......

// A.js
window.A = window.B || function() {
    // ...
};
Run Code Online (Sandbox Code Playgroud)

那么你的代码就有致命的缺陷,因为B依赖于A而A取决于B,必须首先定义一个.这就是所谓的"循环依赖".

要求有同样的问题,只有它更容易被遗漏,因为需要从你身上抽取很多东西.尽管Require(是JavaScript代码)必须按顺序运行,这意味着它必须按某种顺序定义模块.如果模块A依赖于模块B,并且B依赖于A,则您将具有相同的循环依赖性问题.

类似地,如果你有一个依赖于B的A,而依赖于C的B和依赖于A的C,你也会有一个循环依赖.或者如果你有一个依赖于D的C依赖......那么你就明白了.最终,依赖于任何其他模块的任何模块都必须确保依赖模块或其任何依赖性都不依赖于原始模块.

那你如何修复你的代码呢?显而易见的方法是删除循环依赖项,这肯定会有效,但还有另一种选择.假设您的A取决于B,但仅在运行时,而不是在加载时.换句话说,而不是:

// A.js
define(['B'], function(B) {
    return B || function() {
        // ...
    };
});
Run Code Online (Sandbox Code Playgroud)

你有:

// A.js
define(['B'], function(B) {
    return function() {
        B();
    };
});
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您可以使用require的单个参数"synchronous"形式,以避免在文件顶部需要"B":

// A.js
define([], function() {
    return function() {
        var B = require('B');
        B();
    };
});
Run Code Online (Sandbox Code Playgroud)

因为我们在定义了所有模块之后才使用B 要求不必担心A之后的B; 它可以随时定义它,因为当你真正想要使用 B时,它已经被定义了.当然,这假设您有一些实际上在顶部包含"B"的模块(如果您不需要甚至不知道B存在).

希望有所帮助.