如何在JS(浏览器端)中使用`require`和依赖注入,服务位置?

时间:2013-11-12 10:27:43

标签: javascript architecture dependency-injection browserify

所以我一直在玩JS和browserify以允许将我的JS分成更小的文件块。它工作得很好,但是,我仍然对如何正确使用require函数感到迷茫。

对我来说,它充当服务定位器,因为它查找要加载的正确“文件”并返回一个对象。 (例如在PHP中,require稍微将文件加载到内存中但不construct)。

示例:

var Foo = function() {
    console.log("I'm the Foo object");
};

module.exports = Foo;

然后,使用它我会做:

var Foo = require('foo');

var foo = new Foo();

请注意,导出的函数是 NOT 构造的。

我本可以做到:

var foo = require('foo')();

这些方法对我来说都不对(我可能错了)。

  • 1)这样做是否常见?或者应该导出已执行的函数?

无论如何,这个介绍是为了理解我应该如何使用require函数。

例如,如果我有一个Foo对象,这取决于Bar,我有两种方法可以做:

服务地点

var Foo = function() {
   var Bar = require('bar')();

   Bar.doSomethingAwesome();
};

module.exports = Foo;

或者我能做到:

依赖注入

var Foo = function(bar) { 
   bar.doSomethingAwesome();
};

module.exports = Foo;

// And at a latter time

var foo = require('foo')(require('bar')); /// eurk

我显然知道这是两件不同的事情并且有不同的用途。

  • 2)但我想知道在JS中常见/正确的做法是什么,是否有任何普遍承认的规则?

3 个答案:

答案 0 :(得分:0)

Browserify允许您使用模块进行编程,其中没有更多内容。它本身并不是一个DI容器或服务定位器,尽管你可能会让它像一个一样工作。

这样做非常好:

var Foo = require('foo');
var foo = new Foo();

在这种情况下,简单地将所有require调用放在文件顶部是有意义的,就像在C#中使用using或在Java中使用import一样。我个人不会分散require个电话,因为对可读性没什么帮助。

您还可以导出不再需要新建的实例,只要该实例适合您想要执行的操作(在这种情况下module.exports = Foo()会导致单例)。

另见相关问题: Dependency Injection with RequireJS

答案 1 :(得分:0)

rewire库为Node.js提供模块注入。 已经在this Github issue中讨论并提供了几个解决方案以支持browserify。

项目README中的用法示例:

var myModule = rewire("../lib/myModule.js");
myModule.__set__("fs", fsMock); // set private variable

答案 2 :(得分:0)

使用Browserify,这样您就可以像浏览器一样从浏览器中获取npm包。然后你可以使用Weather.js或者需要它,然后以你喜欢的任何方式注入它。