试图模块化现有的大型Node + Express + Mongoose 应用到多个可安装的应用程序,每个应用程序开发为 单独的NPM包,我们想知道是否共享一个 他们之间的Mongoose实例是个好主意?
假设我们有一套NPM包,每个包含客户端资产, Mongoose模型和使用Express实现的REST-API。他们分享 一些共同的特征,但基本上被认为是分开的 可重复使用的文物。主机应用程序也是基于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
拉入)使用Mongoose,就像使用
主机应用程序本身,我们想通过主机Mongoose实例传递
通过某种environment
对象,也包括其他对象
主持人希望与已安装的应用共享的内容。
你认为这种方法存在明显的缺陷吗?已安装的应用
在这种情况下,不将Mongoose指定为其中的依赖项
各自package.json
,他们不 require('mongoose')
正常情况下,但从主机获取Mongoose实例
负责将其连接到MongoDB。
如果这是一个坏主意,您建议每个子应用程序声明一个依赖项 对于Mongoose而言,每个NPM包都会得到自己的 Mongoose的副本,每个都必须连接到MongoDB,对吗?
一些背景信息:
修改:在npm install
编辑完所有内容后澄清包结构:
host/
assets/
models/
routes/
node_modules/
express/ ...
mongoose/ ...
events/
assets/ ...
models/ ...
routes/ ...
tickets/
assets/ ...
models/ ...
routes/ ...
discussions/
assets/ ...
models/ ...
routes/ ...
也就是说,events
,tickets
和discussions
应用不包含在内
Mongoose(或Express)属于他们自己但设计依赖于永远存在的
提供这些依赖项的主机应用程序。
我们在此假设像tickets
这样的NPM包不能简单
来自父母的require
东西,对吧?
答案 0 :(得分:6)
如果要在其他NPM包之间重用Mongoose包,最好的方法是在顶级应用程序中安装共享包,然后使用它来初始化其他NPM包。
在顶层:
var db = require('myMongooseDb'),
events = require('events')(db),
...
然后你的事件包只需要导出一个以db作为参数的函数。
答案 1 :(得分:3)
我建议您查看https://github.com/jaredhanson/node-parent-require,这是最近发布的一个解决了这个问题的方法。
Github项目页面上的node-parent-require Readme file提供了使用mongoose的详细演练。
基本上,您需要挖掘子模块并替换它:
mongoose = require("mongoose");
......用这个:
try {
var mongoose = require('mongoose');
} catch (_) {
// workaround when `npm link`'ed for development
var prequire = require('parent-require')
, mongoose = prequire('mongoose');
}
不要忘记在子模块的package.json中添加mongoose作为peerDependency。例如:
"peerDependencies": {
"mongoose": "3.x"
}
您可能还想先阅读http://blog.nodejs.org/2013/02/07/peer-dependencies/。
答案 2 :(得分:0)
const mongoose = require('mongoose-global')();
您可以只需要一个全局的mongoose实例并在任何地方使用它。