2015-12-04 33 views
0

我一直在使用一些自定義Node.js模塊的項目。我創建了一個 '助手' 模塊,與裝載協助一些輔助方法:Catch-22遞歸節點模塊在使用摩卡時炸掉了

/helpers/index.js:

var mutability = require('./mutability'), 
    cb = require('./cb'), 
    build = require('./build'), 
    userAgent = require('./userAgent'), 
    is = require('./is'), 
    query = require('./query'), 
    config = require('./config'), 
    _ = require('underscore') 

module.exports = _.extend({ 
    cb: cb, 
    build: build, 
    userAgent: userAgent, 
    is: is, 
    query: query, 
    config: config 
}, mutability) 

爲了好玩,mutability.js是:

'use strict' 

module.exports = { 
    setReadOnly: function(obj, key) { 
     // whatever 
     return obj 
    }, 
    setWritable: function(obj, key) { 
     // whatever 
     return obj 
    } 
} 

我的模塊之一,build,需要一個類來做一些類型檢查:

/helpers/build.js

'use strict' 

var urljoin = require('url-join'), 
    config = require('./config'), 
    cb = require('./cb'), 
    Entity = require('../lib/entity'), 
    _ = require('underscore') 

module.exports = { 
    url: function(options) { 
     return urljoin(
      config.baseUrl, 
      options.client.orgId, 
      options.client.appId, 
      options.type, (typeof options.uuidOrName === 'string') ? options.uuidOrName : "" 
     ) 
    }, 
    GET: function(options) { 
     options.type = options.type || args[0] instanceof Entity ? args[0]._type : args[0] 
     options.query = options.query || args[0] instanceof Entity ? args[0] : undefined 
     return options 
    } 
} 

而且Entity則需要helpers

/lib/entity.js

'use strict' 

var helpers = require('../helpers'), 
    ok = require('objectkit'), 
    _ = require('underscore') 

var Entity = function(object) { 
    var self = this 

    _.extend(self, object) 

    helpers.setReadOnly(self, ['uuid']) 

    return self 
} 

module.exports = Entity 

無論出於何種原因,當我和摩卡運行此,我得到helpers註銷爲{}和摩卡拋出:

Uncaught TypeError: helpers.setReadOnly is not a function 

當我運行/lib/entity.js直接與node,它打印適當的模塊。是什麼賦予了?摩卡爲什麼炸燬?

+0

你沒有給我們看的'/ helpers/mutability.js'模塊似乎是最相關的 – Bergi

+0

娜,我不這麼認爲。如果我直接需要'var mutability = require('/ helpers/mutability')'它工作得很好。我實際上傾向於這是一個摩卡錯誤,因爲它不是*只是*缺少可變性,它是整個幫助者對象。 – brandonscript

回答

1

你是正確的問題是你的循環依賴index.jsentity.js之間。

你的依賴關係圖看起來像這樣(與歸一化的路徑),其中每個箭頭是require語句:

/helpers/index.js -> /helpers/build.js -> /lib/entity.js -> /helpers/index.js 

當模塊處於節點module.exportsrequired被初始化爲一個空對象。

當你有一個循環依賴則可能是這個默認的對象是之前你的代碼返回到另一個模塊已運行到實際設置module.exports = ...;(因爲JavaScript是同步)。

這就是你的情況發生了什麼:/lib/entity.js正在從/helpers/index.js接收默認導出對象,然後index.js已定義它的module.exports = _.extend(...)

要解決它,你需要確保你擴展的,而不是用新的實例替換它已經回到了/lib/entity.js同一個對象,:

// Extend `module.exports` instead of replacing it with a new object. 
module.exports = _.extend(
    module.exports, 
    { 
     cb: cb, 
     build: build, 
     userAgent: userAgent, 
     is: is, 
     query: query, 
     config: config 
    }, 
    mutability 
); 

然而,一般最好避免循環依賴如果可能的話。

+0

該死的,這是堅果!雖然有意義,但謝謝你的好建議。通常我不想循環引用,但在這種情況下,由於我只用它來檢查類型,我認爲它會好的。 – brandonscript