Node.js module.exports不导出整个对象

时间:2015-12-13 11:52:30

标签: node.js express orm sequelize.js

我正在尝试使用sequelizejs和express。这些模型被组织成多个目录。

Users(directory)

users.js
profile.js
...

Articles

article.js
comments.js
...

我修改了sequelize-express示例以遍历子目录并使用promises导入模型。

sequelize_init.js

'use strict';

var fs = require('fs'),
path = require('path'),
_ = require('lodash'),
config = require('./auth-config'),
Sequelize = require('sequelize'),
glob = require('glob'),
Q = require('q'),
db = {};

var sequelize;

function getGlobbedModels() {
    var deferred = Q.defer();
    glob('./config/sequelize/models/**/*.js', function(err, files) {
        if(err)
            deferred.reject('Glob Error' + err);
        else
            deferred.resolve(files);
    });
    return deferred.promise;
}

function importModels(models){
    var deferred = Q.defer();
    for (var i = models.length - 1; i >= 0; i--) {
        if(!i) {
            deferred.resolve('Successfully Required');
        }
        var model = sequelize.import(path.resolve(models[i]));
        db[model.name] = model;
    }
    return deferred.promise;
}

function associateModels(resp) {
    var deferred = Q.defer();
    var models = Object.keys(db);
    for (var i = models.length - 1; i >= 0; i--) {
        if(!i) {
            deferred.resolve();
        }
        if(db[models[i]].options.hasOwnProperty('associate')) {
            db[models[i]].options.associate(db);
        }
    }
    return deferred.promise;
}

function synchronize() {
    // Synchronizing any model changes with database. 
    sequelize
        .sync({
            force: process.env.FORCE_DB_SYNC
        })
        .then(function () {
            console.info('Database synchronized');
        }).catch(function (err) {
            console.error('An error occurred: ', err);
        });
}

if(process.env.NODE_ENV === 'PRODUCTION') {
    //Use production DB
}else {
    //Use local DB
    sequelize = new Sequelize(...);
}

getGlobbedModels()
    .then(importModels)
        .fail(function(err){
            console.error('importModels err ' + err);
        })
    .then(associateModels)
        .fail(function(err){
            console.error('associateModels err' + err);
        })
    .then(synchronize)
        .fail(function(err){
            console.error('synchronize err' + err);
        });

// assign the sequelize variables to the db object and returning the db. 
module.exports = _.extend({
    sequelize: sequelize,
    Sequelize: Sequelize
}, db);

在我的app.js文件中,我需要以下代码,但导出到require调用时模型未定义。我已经验证了上面的db对象,并且成功需要模型,但不会导出到require调用。

app.js

var models = require('./sequelize_init.js');
models.User.findAll().then(); // Throws undefined error

1 个答案:

答案 0 :(得分:1)

在设置module.exports很久之后,您的模型将被异步导入,关联等等,因此当您在模块末尾合并它时,db仍然是一个空对象。

对此的一个解决方案是改为导出初始化函数,该函数接受在所有初始化步骤完成后调用的回调。例如:

<强> sequelize_init.js

// ...

module.exports = function(cb) {
  getGlobbedModels()
      .then(importModels)
          .fail(cb)
      .then(associateModels)
          .fail(cb)
      .then(synchronize)
          .fail(cb)
      .then(function() {
        cb(null, _.extend({
          sequelize: sequelize,
          Sequelize: Sequelize
        }, db));
      });
};

<强> app.js

var init = require('./sequelize_init.js');
init(function(err, models) {
  if (err) throw err;

  models.User.findAll().then();
});