NodeJS和Javascript(requirejs)依赖注入

时间:2011-12-02 06:02:43

标签: javascript node.js dependency-injection express requirejs

我目前正在使用requirejs来管理模块js / css依赖项。 我想发现节点通过集中配置文件执行此操作的可能性。 所以不要手动做像

这样的事情
define([    
'jquery'
'lib/somelib'
'views/someview']

在每个模块中。

我有节点注入依赖项,即

require('moduleA').setDeps('jquery','lib/somelib','views/someview')

无论如何,我对任何寻找节点依赖注入的项目感兴趣。

感谢

3 个答案:

答案 0 :(得分:6)

我想出了依赖注入的解决方案。它被称为injectr,它使用节点的vm库,并在包含文件时替换require的默认功能。

因此,在您的测试中,使用require('libToTest')代替injectr('libToTest' { 'libToMock' : myMock });。我想让界面尽可能简单,不需要改变被测试的代码。我觉得它运作得很好。

值得注意的是,injectr文件是相对于工作目录的,与require相对于当前文件不同,但这并不重要,因为它仅用于测试。

答案 1 :(得分:5)

我之前曾提到过提供备用require以在Node.js中提供依赖注入形式的想法。

模块代码

例如,假设您在 code.js 中有以下语句:     fs = require('fs');

console.log(fs.readFileSync('text.txt', 'utf-8'));

如果您使用node code.js运行此代码,则会打印出 text.txt 的内容。

注射器代码

但是,假设您有一个想要抽象出文件系统的测试模块 您的测试文件 test.js 可能如下所示:

var origRequire = global.require;
global.require = dependencyLookup;
require('./code.js');

function dependencyLookup (file) {
  switch (file) {
    case 'fs': return { readFileSync: function () { return "test contents"; } };
    default: return origRequire(file);
  }
}

如果您现在运行node test.js,它将打印出“测试内容”,即使它包含 code.js

答案 2 :(得分:2)

我还写了一个模块来实现这个目标,它被称为rewire。只需使用npm install rewire然后:

var rewire = require("rewire"),
    myModule = rewire("./path/to/myModule.js"); // exactly like require()

// Your module will now export a special setter and getter for private variables.
myModule.__set__("myPrivateVar", 123);
myModule.__get__("myPrivateVar"); // = 123


// This allows you to mock almost everything within the module e.g. the fs-module.
// Just pass the variable name as first parameter and your mock as second.
myModule.__set__("fs", {
    readFile: function (path, encoding, cb) {
        cb(null, "Success!");
    }
});
myModule.readSomethingFromFileSystem(function (err, data) {
    console.log(data); // = Success!
});

我受Nathan MacInnes's injectr的启发,但采用了不同的方法。我不使用vm来评估测试模块,实际上我使用节点自己的需求。这样,您的模块就像使用require()一样(除了您的修改)。完全支持调试。