Совместное использование экземпляра Мангуста между несколькими пакетами NPM


В попытке модуляризовать большой существующий узел + Экспресс+Мангуст приложение в несколько монтируемых приложений, каждое из которых разработано как отдельный пакет NPM, мы задаемся вопросом, является ли совместное использование одного Пример мангуста между ними-хорошая идея?

Предположим, у нас есть набор пакетов NPM, каждый из которых содержит клиентские активы., Модели мангустов и REST-API, реализованные с помощью Express. Они действительно делятся несколько общих черт, но по существу должны рассматриваться отдельно многоразовые артефакты. Хост-приложение, также основанное на Express, монтирует их под различными корневыми URI:

var discussions = require('discussions'),
    tickets     = require('tickets'),
    events      = require('events'),
    express     = require('express'),
    app         = express();

var environment = { ...see below... };

...

app.use('/events-api', events(environment));
app.use('/tickets-api', tickets(environment));
app.use('/discussions-api', discussions(environment));

Теперь, поскольку events, tickets и discussions приложения (отдельные пакеты NPM втягивается через хост package.json) Используйте Мангуста, как это делают само приложение хоста, мы полагали, что мы будем проходить в экземпляре хоста Мангуста через какой-то объект environment, который также включает в себя другие материал, которым хост хочет поделиться с подключенными приложениями.

Видите ли вы какие-либо очевидные недостатки в этом подходе? Смонтированные приложения в в этом случаене будет указывать Мангуста как зависимость в их соответственно package.json, и они бы не require('mongoose') как обычно, но вместо этого получить экземпляр Мангуста от хозяина который отвечает за подключение его к MongoDB.

Если это плохая идея и вы предлагаете каждому вложенному приложению объявить зависимость к Мангусту самостоятельно, каждый пакет НПМ получит свой собственный копия Мангуста, и каждый из них должен был бы подключиться к MongoDB, верно?

Некоторые предпосылки информация:

  • Мы действительно хотим включить приложения в хост-приложение, запущенное в одном процессе, а не с несколькими экземплярами узлов. То хост содержит промежуточное ПО для аутентификации и других вещей.
  • Мы хотим, чтобы приложения были включены как отдельно разработанные пакеты NPM как версионные зависимости различных хост-приложений, которые мы строим, вместо того, чтобы просто копировать их источник в ведущее приложение.
  • Мы понимаем, что повторное использование одного и того же Экземпляр мангуста между несколькими смонтированные приложения будут иметь общее пространство имен модели.

Edit: для уточнения структуры пакета после того, как все было npm installed:

host/
  assets/
  models/
  routes/
  node_modules/
    express/ ...
    mongoose/ ...
    events/
      assets/ ...
      models/ ...
      routes/ ...
    tickets/
      assets/ ...
      models/ ...
      routes/ ...
    discussions/
      assets/ ...
      models/ ...
      routes/ ...

То есть events, tickets, и discussions приложения не включают Мангусты (или экспресс) сами по себе, но предназначены для того, чтобы полагаться на всегда присутствующий хост-приложение, которое поставляет эти зависимости.

Мы предполагаем, что пакет NPM, подобный tickets, не может просто require материал из родитель, верно?

3 7

3 ответа:

Если вы хотите повторно использовать пакет Mongoose между другими пакетами NPM, лучший способ сделать это-установить общий пакет в приложении верхнего уровня, а затем использовать его для инициализации других пакетов NPM.

На верхнем уровне:

var db = require('myMongooseDb'),
    events = require('events')(db),
    ...

Тогда ваш пакет событий просто должен экспортировать функцию, которая принимает БД в качестве параметра.

Я предлагаю вам взглянуть на https://github.com/jaredhanson/node-parent-require , недавно опубликованный пакет, который решил эту проблему для меня.

Файлnode-parent-require Readme на странице проекта Github предоставляет подробное пошаговое руководство с использованием мангуста.

В принципе, вам нужно покопаться в своем подмодуле и заменить это:

mongoose = require("mongoose");

... с этим:

try {
  var mongoose = require('mongoose');
} catch (_) {
  // workaround when `npm link`'ed for development
  var prequire = require('parent-require')
    , mongoose = prequire('mongoose');
}

Не забудьте добавить Мангуста в качестве peerDependency в пакет вашего подмодуля.формат JSON. Например:

"peerDependencies": {
  "mongoose": "3.x"
}

Вы также можете прочитать http://blog.nodejs.org/2013/02/07/peer-dependencies / первый.

const mongoose = require('mongoose-global')();

Вы можете просто потребовать один глобальный экземпляр мангуста и использовать его в любом месте.

Https://www.npmjs.com/package/mongoose-global