решение циклической зависимости в узле с помощью requirejs

Я пробовал много предложений, которые я нашел в поиске циклической зависимости в узле и requirejs. К сожалению, у меня не получается. Попытка, которая закрыта для решения (я думаю), приведена ниже:

// run.js
var requirejs = require('requirejs');

requirejs.config({
  baseUrl: __dirname,
  nodeRequire: require
});

requirejs(['A'], function(A) {
  var a = new A.Go();
  console.log(a.toon())
});


// A.js
define(['B', 'exports'], function(B, exports) {

  exports.Go = function() {
    var b = new require('B').Ho();
    var toon = function() {
      return 'me tarzan';
    }; 

    return {
      b: b,
      toon: toon
    }
  };
});


// B.js
define(['A', 'exports'], function(A, exports) {

  exports.Ho = function() {
    var a = new require('A').Go();
    var show = function() {
      return 'you jane';
    }

    return {
      a: a,
      show: show
    }
  };
});

Запуск этого кода в узле приводит к ошибке RangeError: превышен максимальный размер стека вызовов Мы удаляем зависимость B от A.js, возвращается «me tarzan»

Любое предложение приветствуется!


person donnut    schedule 28.09.2012    source источник
comment
Вы должны использовать конструкторы A и B, полученные вашей функцией в качестве первого аргумента: 'new require('A').Go();' следует читать '(новый A).Go()' (то же самое для B, конечно). Я не знаю, поможет ли это с циклической зависимостью.   -  person Sergio Cinos    schedule 28.09.2012
comment
@Sergio Вы правы, обычно я бы так не делал. Этот метод предлагается в документе API requirejs. При использовании (new B).Ho() возникают ошибки: TypeError: object is not a function, вероятно, потому, что B в этот момент неизвестен.   -  person donnut    schedule 28.09.2012
comment
О, я не знал об этом случае. Спасибо за вашу поправку.   -  person Sergio Cinos    schedule 28.09.2012


Ответы (1)


Циклические ссылки — это нормально, и они не обязательно являются признаком плохого дизайна. Вы можете возразить, что наличие большого количества крошечных модулей может быть столь же вредным, потому что код/логика разбросаны.

Чтобы избежать ужасного TypeError: Object #<Object> has no method, вам нужно позаботиться о том, как вы инициализируете module.exports. Я уверен, что нечто подобное применяется при использовании requirejs в узле, но я не использовал requirejs в узле.

Проблема вызвана тем, что узел имеет пустую ссылку на модуль. Это легко исправить, присвоив значение экспорту перед вызовом require.

function ModuleA() {
}

module.exports = ModuleA;  // before you call require the export is initialized

var moduleB = require('./b');  //now b.js can safely include ModuleA

ModuleA.hello = function () {
  console.log('hello!');
};

Этот пример взят с сайта https://coderwall.com/p/myzvmg, где доступна дополнительная информация.

person Tom Carchrae    schedule 24.01.2014