Require возвращает пустой объект


126

У меня есть папка с index.js и парочкой моделей (классов) index.js

module.exports = {
   Book : require('./book'),
   Author : require('./author')
}

book.js

var Author = require('./author')
var Book = models.ActiveRecord.extend({
    schema : {
        belongsTo : {
            author : Author
        }
    }
})
module.exports = Book

author.js

var Book = require('./book')
var Author = models.ActiveRecord.extend({
    schema : {
        hasMany : {
            author : Book
        }
    }
})

module.exports = Author

Проблема в том, что класс Author не находит Книгу! Это просто пустой объект. Однако, если я переключу экспорт в index.js, поставив книгу после автора - это работает, но тогда другая модель перестанет работать.

Я не хочу делать какие-либо хаки, чтобы заставить его работать.


4
Author.js требует для запуска Book.js, а для Book.js - Author.js? Удалите круговую зависимость.
— Филипп Гайрет

1
Что это за объект ActiveRecord? Откуда это?
— BT

Ответы:


208

Это потому, что у вас круговая зависимость. Node.js обрабатывает это очень специфическим образом:

  1. Первый модуль загружается и запускается (в данном случае book.js). Он ( book.js) загрузит и запустит второй модуль ( author.js), когда ему ( book.js) потребуется другой ( author.js)

  2. Когда второй модуль ( author.js) загружается и запускается, ему ( author.js) требуется первый модуль ( book.js), но он ( author.js) получит частично заполненный объект - несмотря на то, что многие вещи были установлены для экспорта в book.js до того, как это потребовалось, author.js будет быть в этом объекте

  3. После того, как book.jsбудет полностью проходить через объект author.jsполучил от require('./book')будет полный book.jsобъект модуля

Для получения дополнительной информации вот документы: http://nodejs.org/api/modules.html

Если возможно динамически добавить эту схему к одному из этих объектов ActiveRecord, это один из способов решить эту проблему. На самом деле это довольно сложная ситуация. Фактически, даже без модульной системы это вызвало бы у вас проблемы. Если вы поместите весь этот код в один файл, как бы вы заставили его работать?


1
Я знаю, что вам не следует помещать все в один файл, но я говорю, что просто экспериментируйте. Я хочу сказать, что проблема здесь не в модульной системе node.js, а в самом коде.
— BT

И на самом деле у Java есть те же проблемы с зависимостями Circlar - это проблема, которая может быть у любого языка. Если все, что вам нужно, это ссылка на вашего партнера по циклической зависимости, javascript может сделать это так же легко, как java. Однако здесь вы пытаетесь использовать объект до того, как он будет построен (в дальнейшем)
— BT

Да, теперь я понял это. Никогда не приходило в голову. Так что есть только один способ - я думаю, добавить его динамически. Или передать название модели в виде строки. Спасибо за ваш ответ!
— user3677173

18
Я настоятельно рекомендую Мэдж для отладки такого рода проблем в более сложных случаях (например, с большим количеством файлов). После установки вы можете использовать madge -c <app entry point>для обнаружения любых циклических зависимостей.
— schu34

7
Спасибо. Довольно болезненно, что он даже не выдает ошибку, а просто возвращает пустой объект.
— Роберт Ошлер
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.