2015-12-04 28 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