我如何在JavaScript中模块化我的代码?

我正在使用Parse.com javascript for CloudCode。 我没有兴趣成为JavaScript的专家,但我需要做一些。 我已经制定了一个模块化(分成单独的文件)的scheme,但似乎必须有一个更好的方法。 在我的main.js ,我有这样的代码。 main.js的唯一function是将各个模块调用并链接在一起。

 var mods = {}; mods.functions = require('cloud/functions.js'); mods.user = require('cloud/user.js'); mods.functions.setMods(mods); 

modsvariables收集每个模块的引用。 然后,对于需要调用其他模块的每个模块,我会在该模块中调用“setMods”并将mods传递给它。 在setMods中,模块获取其他任何想要访问的模块的引用。

每个模块都有这样的代码。

 exports.setMods = function (mods) { userMod = mods.user; constants = mods.constants; }; Parse.Cloud.define("getRecoveryQuestion", function(request, response) { var p0 = userMod.lookupUserByEmail(request.params.email); var p1 = p0.then(function(user) { // result is a User // Now look for the password recovery question if (user) { // Found it var question = user.get("pwdRecoveryQuestion"); response.success(question); } else { response.success(null); } return null; }); }); 

在用户模块中,导出的函数看起来就是这样。

 exports.lookupUserByEmail = function (email) // returns null when not found { var User = Parse.Object.extend("User"); var query = new Parse.Query(User); query.equalTo("email", email); var p0 = query.first(); var p1 = p0.then( function(result) { return result; } ); return p1; }; 

那么,有没有更好的解决这个问题?

没有必要在main.js中集中模块导入。 node.js 的每个文件都是最有可能拥有私有代码并导出接口的模块。 它可以根据需要导入多个模块。 这是导入模块的依赖关系的简单方法:

getRecoveryQuestion定义

 var userMod = require('cloud/user.js'), constants = require('cloud/constants.js); Parse.Cloud.define("getRecoveryQuestion", function(request, response) { var p0 = userMod.lookupUserByEmail(request.params.email); var p1 = p0.then(function(user) { // result is a User // Now look for the password recovery question if (user) { // Found it var question = user.get("pwdRecoveryQuestion"); response.success(question); } else { response.success(null); } return null; }); }); 

用户模块看起来像这样。

云/ user.js的

 exports.lookupUserByEmail = function (email) // returns null when not found { var User = Parse.Object.extend("User"); var query = new Parse.Query(User); query.equalTo("email", email); var p0 = query.first(); var p1 = p0.then( function(result) { return result; } ); return p1; }; 

请记住,你传递的是一个模块ID。 它可以是一个path(就像上面的例子一样)或者是一个在项目根目录下的node_modules文件夹中查找的模块名称。 几个分析提供的模块将在你的平台上。 在前面的例子中,我假定constants.jsuser.js都在cloud目录中。

但是,你在代码中做什么看起来更像是dependency injection。 在编码时,您可能需要执行dependency injection的几个原因(但是,在为代码库添加一层复杂性之前,请确认您已经这么做了)。 Node的module.require实现了模块模式,这使得DI过时了。

dependency injection的主要原因之一是testing。 您可以通过使用一个名为proxyquire的方便库来更改require返回的内容 ,从而避免使用dependency injection库/框架。

如果你有其他的理由去做DI(例如,如果你对代码的耦合感觉不舒服 ,或者其他的话),有些人已经为它编写了库。 检查这个问题 。