que online example babelify javascript backbone.js require browserify

javascript - online - browserify transform



Browserify require devuelve un objeto vacĂ­o (1)

Tengo este código que, por razones que no puedo entender, produce un objeto vacío al usar require() . Mi estructura de archivos es así:

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

El archivo problemático es collections/listings.js , que parece simplemente generar como un objeto vacío cuando así lo requiere:

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

src/public/javascript/collections/listings.js ve así:

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

Aquí hay un ejemplo de donde las cosas van mal:

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

Así que ahí está - Esa colección nunca requiere en el modelo de empleador de modo que se pueda usar para crear una colección de elementos secundarios para el modelo principal. Miré la fuente e investigué este problema, pero hasta ahora no he encontrado nada ... Es desconcertante.


Dado que mi comentario parece haber respondido a este problema, pensé en escribirlo formalmente.

Al usar Require.js, debe pensar en las dependencias entre los módulos. En cierto sentido, este es el mismo problema que si no estuviera usando require. Supongamos que tiene dos archivos, A.js y B.js, que definen una función "A" y una función "B", respectivamente:

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

Puede agregar esos archivos en cualquier orden a su página, y su código funcionará. Pero, ¿qué sucede si su definición de "B" depende de la definición de "A"?

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

Ahora, de repente importa el orden: debe incluir su archivo B.js después de su archivo A.js o, de lo contrario, el código de B no funcionará. Y si tu A.js también depende de tu B.js ...

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

Entonces su código es fatalmente defectuoso, porque B depende de A y A depende de B, y uno tiene que definirse primero. Esto es lo que se conoce como "dependencia circular".

Requieren tiene el mismo problema, solo que es más fácil pasar por alto porque Require resume muchas cosas de usted. Al final del día, aunque Require (que es un código de JavaScript) tiene que ejecutarse de forma secuencial, lo que significa que tiene que definir sus módulos en algún orden. Si su módulo A depende del módulo B y B depende de A, tendrá el mismo problema de dependencia circular.

De manera similar, si tiene A que depende de B, y B depende de C, y C depende de A, también tendrá una dependencia circular. O si tienes una C que depende de D, eso depende ... bueno, entiendes la idea. En última instancia, cualquier módulo que dependa de cualquier otro módulo debe garantizar que ni el módulo dependiente ni ninguna de sus dependencias dependan del módulo original.

Entonces, ¿cómo arreglas tu código? La forma obvia sería eliminar las dependencias circulares, que sin duda funcionarán, pero también hay otra opción. Digamos que su A depende de B, pero solo en tiempo de ejecución , no en tiempo de carga . En otras palabras, en lugar de:

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

tienes:

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

En este caso, puede usar el único argumento "synchronous" de require para evitar tener que requerir "B" en la parte superior de su archivo:

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

Porque solo usamos B después de que hayamos definido todos nuestros módulos. Requerir no tiene que preocuparse de que A venga después de B; puede definirlo cuando lo desee porque, cuando realmente quiera usar B, ya estará definido. Por supuesto, esto supone que tienes algún módulo que realmente incluye "B" en la parte superior (si no lo necesitas ni siquiera sabrías que B existe).

Espero que ayude.