在 Mongoose 项目之间共享模式
在大型组织中,通常会有一个包含多个项目之间共享的模式的项目。例如,假设您的公司有一个@initech/shared-schemas
私有 npm 包,而npm list
看起来如下所示
@initech/[email protected]
├── @initech/[email protected]
├── [email protected]
在上面的输出中,@initech/web-app1
是一个客户端项目,而@initech/shared-schemas
是共享库。
将 Mongoose 作为对等依赖项
首先,也是最重要的一点,我们建议@initech/shared-schemas
在您共享的模式的peerDependencies
中列出 Mongoose,而不是作为顶级依赖项。例如,@initech/shared-schemas
的package.json
应该如下所示。
{
"name": "@initech/shared-schemas",
"peerDependencies": {
"mongoose": "8.x"
}
}
我们推荐这种方法的原因如下
- 更容易升级。例如,假设
@initech/shared-schemas
依赖于 Mongoose 8,而@initech/web-app1
可以很好地与 Mongoose 8 协同工作;但是,@initech/web-app2
无法从 Mongoose 7 升级。对等依赖关系使依赖于共享模式的项目更容易确定他们想要的 Mongoose 版本,而不会冒出现 Mongoose 模块版本冲突的风险。 - 减少 Mongoose 模块重复的风险。不支持将来自一个版本的 Mongoose 的 Mongoose 模式和模型与另一个版本的 Mongoose 一起使用。
导出模式,而不是模型
我们建议@initech/shared-schemas
导出 Mongoose 模式,而不是模型。这种方法更加灵活,允许客户端项目使用其首选模式实例化模型。特别是,如果@initech/shared-schemas
导出使用mongoose.model()
注册的模型,则无法将该模型传输到另一个连接。
// `userSchema.js` in `@initech/shared-schemas`
const userSchema = new mongoose.Schema({ name: String });
// Do this:
module.exports = userSchema;
// Not this:
module.exports = mongoose.model('User', userSchema);
解决方法:导出 POJO
有时,现有的共享库不遵循上述最佳实践。如果您发现自己有一个依赖于旧版本的 Mongoose 的共享库,一个有用的解决方法是导出POJO,而不是模式或模型。这将消除共享库的 Mongoose 版本与客户端项目的 Mongoose 版本之间的任何冲突。
// Replace this:
module.exports = new mongoose.Schema({ name: String });
// With this:
module.exports = { name: String };
并更新您的客户端项目以执行以下操作
// Replace this:
const { userSchema } = require('@initech/shared-schemas');
// With this:
const { userSchemaDefinition } = require('@initech/shared-schemas');
const userSchema = new mongoose.Schema(userSchemaDefinition);