Утилизация зависимостей NodeJS и Javascript (requirejs)

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

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

внутри каждого модуля.

Я бы использовал node вложения зависимостей, т.е.

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

В любом случае, меня интересуют любые проекты, которые ищут инъекцию зависимостей для node.

спасибо

Ответ 1

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

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

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

Ответ 2

Я уже играл с идеей предоставления альтернативного 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.

Ответ 3

Я также написал модуль для этого, он называется 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 injectr, но использовал другой подход. Я не использую vm для оценки тестового модуля, на самом деле я использую node собственный запрос. Таким образом, ваш модуль ведет себя точно так же, как с помощью require() (кроме ваших изменений). Также полностью поддерживается отладка.