简体   繁体   English

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

[英]How do I modularize my code in JavaScript?

I am using Parse.com javascript for CloudCode. 我正在将Parse.com javascript用于CloudCode。 I have little interest in becoming an expert in javascript, but I need to do some. 我对成为javascript专家没什么兴趣,但是我需要做一些事情。 I have worked out a scheme for modularizing (dividing into separate files) but it seems like there must be a better way. 我已经制定出一种模块化的方案(分为单独的文件),但是似乎必须有一个更好的方法。 In my main.js , I have code like this. 在我的main.js ,我有这样的代码。 The only function of main.js is to call and link the various modules together. main.js的唯一功能是将各个模块调用并链接在一起。

var mods = {};

mods.functions = require('cloud/functions.js');
mods.user = require('cloud/user.js');

mods.functions.setMods(mods);

The mods variable collects references to each module. mods变量收集对每个模块的引用。 Then for each module that needs to call other modules, I call "setMods" in that module and pass mods to it. 然后,对于需要调用其他模块的每个模块,我在该模块中调用“ setMods”并将mod传递给它。 In setMods the module gets references to any other module it wants to access. 在setMods中,模块获取对它要访问的任何其他模块的引用。

Each module then has code like this. 然后,每个模块都有这样的代码。

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;
        });
});

In the User module, the exported function would look this way. 在用户模块中,导出的函数将采用这种方式。

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;
};

So, is there a better solution to this problem? 那么,对于这个问题有更好的解决方案吗?

There's no need to centralize module import in main.js. 无需在main.js中集中导入模块。 Every file in node.js is a module that will most likely have private code and export an interface. node.js 的每个文件都是一个模块,该模块很可能具有私有代码并导出接口。 And it can import as many modules as it needs. 而且它可以根据需要导入任意数量的模块。 This is the simpler way of importing your modules' dependencies: 这是导入模块依赖项的更简单方法:

getRecoveryQuestion definition 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;
        });
});

The User module would look like this. 用户模块如下所示。

cloud/user.js 云/ 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;
};

Please keep in mind that what you pass to require is a module id. 请记住,您传递的require是模块ID。 It can be a path (like in the case above) or a module name that will be looked for in a node_modules folder under the root of the project. 它可以是路径(如上述情况)或模块名称,将在项目根目录下的node_modules文件夹中node_modules Several Parse-provided modules will be there for you in their platform. 平台中将为您提供几个Parse提供的模块。 In the previous example, I assumed both constants.js and user.js were in the cloud directory. 在前面的示例中,我假设constants.jsuser.js都在cloud目录中。

However, what you do in your code looks more like dependency injection. 但是,您在代码中执行的操作看起来更像是依赖项注入。 There are several reasons you might want to do dependency injection when coding (however, confirm that you do before adding one more layer of complexity to your codebase). 在编码时可能要进行依赖注入有多种原因(但是,在向代码库中再增加一层复杂性之前,请先进行确认)。 Node's module.require implements the module pattern, which makes DI obsolete. Node的module.require实现了模块模式,这使得DI已过时。

One of the main reasons for dependency injection is testing. 进行依赖注入的主要原因之一是测试。 You can change what require returns by using a handy library called proxyquire , avoiding the usage of a dependency injection library/framework. 您可以使用名为proxyquire的便捷库来更改require返回的内容 ,避免使用依赖项注入库/框架。

If you have other reasons to do DI (for instance if you still feel uncomfortable about your code's coupling, or whatever), some people have written libraries for it. 如果您还有其他原因要进行DI(例如,如果您对代码的耦合仍然不满意 ,或其他原因),则有人为它编写了库。 Check this SO question . 检查这个SO问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM