外部模块中的模式在Node.js中不起作用

我有一个非常头痛的尝试通过模块共享一些常见模式定义到我的代码库中的所有其他模块。

我有一个包含这两个模式的myproj_schemas模块:

var mongoose = require('mongoose'), util = require("util"), Schema = mongoose.Schema; var BaseProfileSchema = function() { Schema.apply(this, arguments); this.add({ _user: {type: Schema.Types.ObjectId, ref: 'User', required: true}, name: {type: String, required: true}, bio: {type: String, required: true}, pictureLink: String }); }; util.inherits(BaseProfileSchema, Schema); module.exports = BaseProfileSchema; 

 var mongoose = require('mongoose'), BaseProfileSchema = require('./base_profile_schema.js'), Schema = mongoose.Schema; var entSchemaAdditions = { mentors: {type: Schema.Types.ObjectId, ref: 'Mentor'} }; var entrepreneurSchema = new BaseProfileSchema(entSchemaAdditions); module.exports = entrepreneurSchema; 

导师也被定义在另一个文件中。

我的unit testing这两个工作在模式模块。

当我npm安装这个模块,并尝试创build使用

 Entrepreneur = db.model('Entrepreneur', entrepreneurSchema), 

我得到以下错误:

TypeError: paths.mentors未定义types您是否尝试嵌套模式? 你只能使用参考或数组嵌套。

如果我在本地模块中使用相同的代码,那么没有问题。 如果我直接在require中引用模式文件(例如require('../ node_modules / myproj_schemas / models / ent_schema'),那么我得到错误。

我相当肯定,它之前没有这样的突破,但我已经退出了所有的变化,但仍然无法正常工作。

我正在绘制一个完整的空白,任何build议将受到感谢。

编辑:

我已经创build了一个新的Schemas模块。 它有一个Schema:

 var mongoose = require('mongoose'); var userSchema = new mongoose.Schema({ email: String }); module.exports = userSchema; 

封装在模块中时也会失败,npm会安装到其他模块中。

在OS X上运行

就我个人而言,我使用init方法创build了一个单独的“公共”项目,以便用mongodb注册所有模型,并在任何需要访问模型的应用程序的app.js文件中调用init方法。

  1. 创build共享项目 – 按照标​​准过程创build新的节点项目。
  2. package.json – 在共享项目中,将package.json文件设置为包含以下条目:

     "main": "index.js" 
  3. 添加一个模型 – 在共享项目中创build一个新的models文件夹,以包含所有的mongoose模式和插件。 将您的userSchema文件添加到模型文件夹并将其命名为user.js

     var mongoose = require('mongoose'); var userSchema = new mongoose.Schema({ email: String }); module.exports = mongoose.model('User', userSchema); 
  4. index.js – 然后在项目的根目录index.js文件中创build一个可供你的应用程序使用的共享对象,展示模型和init方法。 有很多方法来编码,但这是我做的:

     function Common() { //empty array to hold mongoose Schemas this.models = {}; } Common.prototype.init = function(mongoose) { mongoose.connect('your mongodb connection string goes here'); require('./models/user'); //add more model references here //This is just to make referencing the models easier within your apps, so you don't have to use strings. The model name you use here must match the name you used in the schema file this.models = { user: mongoose.model('User') } } var common = new Common(); module.exports = common; 
  5. 引用你的common项目 – 但是你想引用你的共享项目,在你的应用程序的package.json文件中添加对共享项目的引用,并给它一个common的名称。 我个人使用GitHub来存储项目,并引用存储库path。 由于我的存储库是私有的,我必须使用GitHub支持站点上覆盖的path中的一个密钥。
  6. 在您的应用程序中初始化模型 – 在您的应用程序的开始脚本中(让我们假设这个例子是app.js )添加对您的common项目的引用,并调用init方法连接到mongodb服务器并注册模型。

     //at the top, near your other module dependencies var mongoose = require('mongoose') , common = require('common'); common.init(mongoose); 
  7. 在应用程序中的任何位置使用模型 – 现在,mongoose已经build立了连接池,模型已经注册,您可以使用模型是应用程序中的任何类。 例如,假设你有一个显示关于user信息的页面,你可以这样做(未经testing的代码,只是这个例子):

     var common = require('common'); app.get('/user-profile/:id', function(req, res) { common.models.user.findById(req.params.id, function(err, user) { if (err) console.log(err.message); //do something else to handle the error else res.render('user-profile', {model: {user: user}}); }); }); 

编辑对不起,我没有看到你从另一个架构inheritance一个架构。 作为其他答案之一,mongoose已经提供了plugin的概念。 在你上面的例子中,你可以这样做:

在您的通用模块中,在“/models/base-profile-plugin.js”

 module.exports = exports = function baseProfilePlugin(schema, options){ //These paths will be added to any schema that uses this plugin schema.add({ _user: {type: Schema.Types.ObjectId, ref: 'User', required: true}, name: {type: String, required: true}, bio: {type: String, required: true}, pictureLink: String }); //you can also add static or instance methods or shared getter/setter handling logic here. See the plugin documentation on the mongoose website. } 

在您的通用模块中,在“/models/entrepreneur.js”下

 var mongoose = require('mongoose') , basePlugin = require('./base-profile-plugin.js'); var entrepreneurSchema = new mongoose.Schema({ mentors: {type: Schema.Types.ObjectId, ref: 'Mentor'} }); entrepreneurSchema.plugin(basePlugin); module.exports = mongoose.model('Entrepreneur', entrepreneurSchema); 

你为什么不创build一个像这样的常见模式的mongoose插件https://github.com/Keeguon/mongoose-behaviors/blob/master/lib/timestampable.js

你正在寻找什么基本上是模式inheritance,有一个名为mongoose扩展的项目,实际上解决了你的问题,你可以决定是否要实现它,或者看看代码,使自己的。

只需要安装一下usng npm

 $ npm install mongoose-schema-extend 

这是如何工作的:

 var mongoose = require('mongoose'), extend = require('mongoose-schema-extend'); var Schema = mongoose.Schema; var PersonSchema = new Schema({ name : String }, { collection : 'users' }); var EmployeeSchema = PersonSchema.extend({ department : String }); var Person = mongoose.model('Person', PersonSchema), Employee = mongoose.model('Employee', EmployeeSchema); var Brian = new Employee({ name : 'Brian Kirchoff', department : 'Engineering' }); 

问候