需要一个使用揭示模块模式的模块

Requiring a module that uses the revealing module pattern

我正在尝试 require 一个自调用 Javascript 函数的模块,并在我 require 它时向它传递一个参数。 'required' 对象总是说 'object is not a function'。

下面的代码是否可行,如果可行,我哪里出错了?

模块

var _ = require('lodash');

var userRepository = (function(userRecords) {

  console.log(userRecords);

  var findByUsername = function(username, cb) {

    //find username in the userNameData
    //this may have been retrieved from the DB or passed in as mock data from the tests
    var user = _.find(userRecords, {
      "email": username
    });

    if (user) {
      return cb(null, user);
    } else {
      return cb(null, null);
    }
  };

  return {
    findByUserName: findByUsername
  };

})();

module.exports = userRepository;

代码中的用法

var userData = require('../test/data/users.json'),
  userRepository = require('../db/userRepository')(userData);


describe('User Repository', function() {
  describe('Find by username', function() {
    it('should return a user record for <user> if the username <username> is found', function() {
      var username = "test@testing.com";
      var user = userRepository.findByUsername(username, function() {});
    });
  });
});

提前感谢您的帮助

您可以将模块声明更改为函数 isstead

var userRepository = function(userRecords) {
  //private props

  return {
    //return object
  };

};

然后可以使用您使用的语法调用它 - require(MODULE_NAME)(data);

userRepository 是一个 IIFE,它 returns 是一个对象,所以当你需要它时,你会收到这个对象——唉,它不是一个函数。

我看到您正在尝试调用 findByUserName,这确实是此对象的 "public" 函数,只需将您的要求行更改为以下内容:

userRepository = require('../db/userRepository');

在这一行之后,userRepository 将是您的 IIFE 返回的对象。然后您可以调用 userRepository.findByUserName()(就像您在示例中一样)而无需对您的代码进行任何进一步修改。

如果您希望userRepositoryuserRecord作为参数(根据您的评论),请不要使用自调用函数,只需导出当前自调用的函数即可。

(直觉上:如果你想从模块外部提供userRecord,你不能让这个函数自调用,你需要导出函数本身来制作它对您的模块的用户可用 - 以便他们可以使用他们拥有的 userRecord 来调用它。)

您的代码当前设置的方式,您正在导出 userRepository,这实际上等于您的匿名函数 {findByUserName: findByUsername} 的 return 值。这解释了为什么您收到错误 Object is not a function.

如果您希望 require 接受一个参数,它必须是一个函数而不是一个对象。