Loading Node.js modules dynamically based on route

前端 未结 3 1370
情话喂你
情话喂你 2020-12-02 13:47

I\'m doing a project in Node.js using express. Here\'s my directory structure:

root
|-start.js
|-server.js
|-lib/
|    api/
|        user_getDetails.js
|             


        
3条回答
  •  情话喂你
    2020-12-02 14:17

    If you know where your scripts are, i.e. you have an initial directory, for example DIR, then you can work with fs, for example:

    server.js

    var fs = require('fs');
    var path_module = require('path');
    var module_holder = {};
    
    function LoadModules(path) {
        fs.lstat(path, function(err, stat) {
            if (stat.isDirectory()) {
                // we have a directory: do a tree walk
                fs.readdir(path, function(err, files) {
                    var f, l = files.length;
                    for (var i = 0; i < l; i++) {
                        f = path_module.join(path, files[i]);
                        LoadModules(f);
                    }
                });
            } else {
                // we have a file: load it
                require(path)(module_holder);
            }
        });
    }
    var DIR = path_module.join(__dirname, 'lib', 'api');
    LoadModules(DIR);
    
    exports.module_holder = module_holder;
    // the usual server stuff goes here
    

    Now your scripts need to follow the following structure (because of the require(path)(module_holder) line), for example:

    user_getDetails.js

    function handler(req, res) {
        console.log('Entered my cool script!');
    }
    
    module.exports = function(module_holder) {
        // the key in this dictionary can be whatever you want
        // just make sure it won't override other modules
        module_holder['user_getDetails'] = handler;
    };
    

    and now, when handling a request, you do:

    // request is supposed to fire user_getDetails script
    module_holder['user_getDetails'](req, res);
    

    This should load all your modules to module_holder variable. I didn't test it, but it should work (except for the error handling!!!). You may want to alter this function (for example make module_holder a tree, not a one level dictionary) but I think you'll grasp the idea.

    This function should load once per server start (if you need to fire it more often, then you are probably dealing with dynamic server-side scripting and this is a baaaaaad idea, imho). The only thing you need now is to export module_holder object so that every view handler can use it.

提交回复
热议问题