首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我是否需要在NodeJS中注入依赖项,或者如何处理...?

我是否需要在NodeJS中注入依赖项,或者如何处理...?
EN

Stack Overflow用户
提问于 2012-02-13 01:19:47
回答 12查看 118.7K关注 0票数 256

我目前正在使用nodejs创建一些实验项目。我用Spring编写了很多Java EE web应用程序,并且很欣赏那里的依赖注入的简单性。

现在我很好奇:如何使用节点进行依赖注入?或者:我甚至需要它吗?有没有替换的概念,因为编程风格不同?

到目前为止,我正在谈论一些简单的事情,比如共享数据库连接对象,但是我还没有找到一个令我满意的解决方案。

EN

回答 12

Stack Overflow用户

发布于 2012-06-04 17:32:20

我还写了一个模块来完成这个任务,它叫做rewire。只需使用npm install rewire,然后:

代码语言:javascript
复制
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来评估测试模块,实际上我使用了node自己的require。这样,您的模块的行为就像使用require()一样(除了您的修改)。此外,还完全支持调试。

票数 37
EN

Stack Overflow用户

发布于 2016-02-08 21:20:14

这是我自己调查过的。我不喜欢引入神奇的依赖utils库,这些库提供了劫持模块导入的机制。取而代之的是,我为我的团队提出了一个“设计指南”,通过在我的模块中引入工厂函数导出,明确地说明可以模拟哪些依赖项。

我在参数和解构方面广泛使用了ES6特性,以避免一些样板,并提供了一种命名的依赖覆盖机制。

下面是一个示例:

代码语言:javascript
复制
import foo from './utils/foo';
import bob from './utils/bob';

// We export a factory which accepts our dependencies.
export const factory = (dependencies = {}) => {
  const {
    // The 'bob' dependency.  We default to the standard 'bob' imp if not provided.
    $bob = bob, 
    // Instead of exposing the whole 'foo' api, we only provide a mechanism
    // with which to override the specific part of foo we care about.
    $doSomething = foo.doSomething // defaults to standard imp if none provided.
  } = dependencies;  

  return function bar() {
    return $bob($doSomething());
  }
}

// The default implementation, which would end up using default deps.
export default factory();

下面是它的用法示例

代码语言:javascript
复制
import { factory } from './bar';

const underTest = factory({ $bob: () => 'BOB!' }); // only override bob!
const result = underTest();

对于那些不熟悉ES6语法的人,请原谅它。

票数 11
EN

Stack Overflow用户

发布于 2013-08-07 17:21:59

我最近检查了这个线程,原因与OP相同--我遇到的大多数库都临时重写了require语句。我使用这种方法的成功程度参差不齐,所以我最终使用了以下方法。

在一个快速应用程序的上下文中-我将app.js包装在一个bootstrap.js文件中:

代码语言:javascript
复制
var path = require('path');
var myapp = require('./app.js');

var loader = require('./server/services/loader.js');

// give the loader the root directory
// and an object mapping module names 
// to paths relative to that root
loader.init(path.normalize(__dirname), require('./server/config/loader.js')); 

myapp.start();

传递给加载器的对象映射如下所示:

代码语言:javascript
复制
// live loader config
module.exports = {
    'dataBaseService': '/lib/dataBaseService.js'
}

// test loader config
module.exports = {
    'dataBaseService': '/mocks/dataBaseService.js'
    'otherService' : {other: 'service'} // takes objects too...
};

然后,不是直接调用require...

代码语言:javascript
复制
var myDatabaseService = loader.load('dataBaseService');

如果加载器中没有别名,那么它将默认为常规要求。这有两个好处:我可以交换任何版本的类,并且它消除了在整个应用程序中使用相对路径名的需要(因此,如果我需要在当前文件之下或之上使用自定义库,我不需要遍历,并且需要根据相同的键缓存模块)。它还允许我在应用程序中的任何位置指定mock,而不是在即时测试套件中。

为了方便起见,我刚刚发布了一个小的npm模块:

https://npmjs.org/package/nodejs-simple-loader

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9250851

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档