В случае, когда я написал модуль, в котором я ожидаю, что кто-то сможет переопределить части внутренних компонентов, я обычно обрабатываю это через параметры в конструкторе.
В модуле:
function A(opts) { }
module.exports = A;
При использовании кода:
var opts = {
...
};
var A = require('./a')(opts);
Где вы бы заменили объект opts тем, что хотели передать в opts. Вы можете сделать это несколькими способами, и у большинства людей есть собственный стиль для такого рода вещей.
Что касается зависимостей и наилучшего подхода, я подозреваю, что вам просто придется принять решение с ним. В конечном счете, если вы не используете только модули внутри npm, вы застрянете, требуя сторонней зависимости. Просто убедитесь, что вы четко указали зависимости, и обрисуйте, как их изменить, если кто-то так решит.