NodeJS and Javascript (requirejs) dependency injection

我怕爱的太早我们不能终老 提交于 2019-12-07 02:56:42

问题


I am currently using requirejs to manage module js/css dependencies. I'd like to discover the possibilities of having node do this via a centralized config file. So instead of manually doing something like

define([    
'jquery'
'lib/somelib'
'views/someview']

within each module.

I'd have node inject the dependencies ie

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

Anyway, I'm interested in any projects looking at dependency injection for node.

thanks


回答1:


I've come up with a solution for dependency injection. It's called injectr, and it uses node's vm library and replaces the default functionality of require when including a file.

So in your tests, instead of require('libToTest'), use injectr('libToTest' { 'libToMock' : myMock });. I wanted to make the interface as straightforward as possible, with no need to alter the code being tested. I think it works quite well.

It's just worth noting that injectr files are relative to the working directory, unlike require which is relative to the current file, but that shouldn't matter because it's only used in tests.




回答2:


I've previously toyed with the idea of providing an alternate require to make a form of dependency injection available in Node.js.

Module code

For example, suppose you have following statements in code.js: fs = require('fs');

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

If you run this code with node code.js, then it will print out the contents of text.txt.

Injector code

However, suppose you have a test module that wants to abstract away the file system.
Your test file test.js could then look like this:

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);
  }
}

If you now run node test.js, it will print out "test contents", even though it includes code.js.




回答3:


I've also written a module to accomplish this, it's called rewire. Just use npm install rewire and then:

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!
});

I've been inspired by Nathan MacInnes's injectr but used a different approach. I don't use vm to eval the test-module, in fact I use node's own require. This way your module behaves exactly like using require() (except your modifications). Also debugging is fully supported.



来源:https://stackoverflow.com/questions/8352374/nodejs-and-javascript-requirejs-dependency-injection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!