Внедрение зависимостей NodeJS и Javascript (requirejs) - PullRequest
6 голосов
/ 02 декабря 2011

В настоящее время я использую requirejs для управления зависимостями js / css модуля.Я хотел бы узнать о возможностях сделать это с помощью централизованного файла конфигурации.Поэтому вместо того, чтобы вручную делать что-то вроде

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

в каждом модуле.

Мне бы пришлось узлу вводить зависимости, т.е.в любых проектах, смотрящих на внедрение зависимостей для узла.

спасибо

Ответы [ 3 ]

6 голосов
/ 01 февраля 2012

Я придумал решение для внедрения зависимостей. Он называется injectr и использует библиотеку vm узла и заменяет функциональность по умолчанию require при включении файла.

Так что в ваших тестах вместо require('libToTest') используйте injectr('libToTest' { 'libToMock' : myMock });. Я хотел сделать интерфейс как можно более простым, без необходимости изменять код, который тестируется. Я думаю, что это работает довольно хорошо.

Стоит только отметить, что файлы инжектора относятся к рабочему каталогу, в отличие от require, который относится к текущему файлу, но это не должно иметь значения, поскольку он используется только в тестах.

5 голосов
/ 29 декабря 2011

Ранее я думал о том, чтобы предоставить альтернативу 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, он напечатает « test content », даже если он включает code.js .

2 голосов
/ 04 июня 2012

Я также написал модуль для этого, он называется 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!
});

Меня вдохновил инжектор Натана Макиннеса , но я использовал другой подход. Я не использую vm для оценки тестового модуля, фактически я использую собственную команду require. Таким образом, ваш модуль ведет себя так же, как при использовании require() (кроме ваших модификаций). Также полностью поддерживается отладка.

...