Подтвердить что ты не робот

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

Файл проблемы 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;
    }
});

Вот пример того, где все идет не так:

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;
    }
});

Итак, это так: эта коллекция никогда не требует от модели работодателя такой, что ее можно использовать для создания дочерней коллекции для родительской модели. Я посмотрел на источник и исследовал эту проблему, но до сих пор ничего не придумал... Это озадачивает.

4b9b3361

Ответ 1

Поскольку мой комментарий, похоже, ответил на эту проблему, я думал, что напишу его формально.

При использовании Require.js вам нужно подумать о зависимостях между модулями. В некотором смысле, это та же проблема, что и вы не использовали. Предположим, что у вас есть два файла: A.js и B.js, которые определяют функцию "A" и функцию "B" соответственно:

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

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

Вы можете добавить эти файлы в любом порядке на свою страницу, и ваш код будет работать. Но что, если ваше определение "B" зависит от определения "A":

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

Теперь, внезапный порядок имеет значение: вы должны включить свой файл B.js после файла A.js, иначе код B не будет работать. И если ваш A.js также зависит от вашего B.js...

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

Тогда ваш код будет смертельно ошибочным, потому что B зависит от A и A зависит от B, и сначала нужно определить. Это то, что известно как "круговая зависимость".

Требовать имеет ту же проблему, только ее легче пропустить, потому что требует от вас абстрактных материалов. В конце дня, хотя Требование (являющееся кодом JavaScript) должно выполняться последовательно, что означает, что он должен определить ваши модули в некотором порядке. Если ваш модуль A зависит от модуля B, а B зависит от A, у вас будет такая же проблема с круговой зависимостью.

Аналогично, если у вас есть A, который зависит от B и B, который зависит от C и C, который зависит от A, вы также будете иметь круговую зависимость. Или, если у вас есть C, который зависит от D, который зависит... ну, вы получите эту идею. В конечном итоге любой модуль, который зависит от любого другого модуля, должен гарантировать, что ни зависимый модуль, ни его зависимости не зависят от исходного модуля.

Итак, как вы исправляете свой код? Очевидным способом было бы удалить круговые зависимости, которые, безусловно, будут работать, но есть и другой вариант. Пусть говорят, что ваш A зависит от B, но только во время выполнения, а не во время загрузки. Другими словами, вместо:

// A.js
define(['B'], function(B) {
    return B || function() {
        // ...
    };
});

у вас есть:

// A.js
define(['B'], function(B) {
    return function() {
        B();
    };
});

В этом случае вы можете использовать единый аргумент "синхронный" форму запроса, чтобы избежать необходимости требовать "B" в верхней части вашего файла:

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

Потому что мы используем только B после того, как мы определили все наши модули. Требовать не нужно беспокоиться о A, идущем после B; он может определять его, когда захочет, потому что к тому времени, когда вы действительно хотите использовать B, он будет уже определен. Конечно, это предполагает, что у вас есть модуль, который на самом деле включает "B" наверху (если вы не требовали, даже не знал бы, что B существует).

Надеюсь, что это поможет.