Can I load multiple files with one require statement?

前端 未结 5 1344
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-13 13:31

maybe this question is a little silly, but is it possible to load multiple .js files with one require statement? like this:

var mylib = require(\'./lib/mylib         


        
相关标签:
5条回答
  • 2020-12-13 14:18

    First of all using require does not duplicate anything. It loads the module and it caches it, so calling require again will get it from memory (thus you can modify module at fly without interacting with its source code - this is sometimes desirable, for example when you want to store db connection inside module).

    Also package.json does not load anything and does not interact with your app at all. It is only used for npm.

    Now you cannot require multiple modules at once. For example what will happen if both One.js and Two.js have defined function with the same name?? There are more problems.

    But what you can do, is to write additional file, say modules.js with the following content

    module.exports = {
       one : require('./one.js'),
       two : require('./two.js'),
       /* some other modules you want */
    }
    

    and then you can simply use

    var modules = require('./modules.js');
    modules.one.foo();
    modules.two.bar();
    
    0 讨论(0)
  • 2020-12-13 14:23

    Yes, you may require a folder as a module, according to the node docs. Let's say you want to require() a folder called ./mypack/.

    Inside ./mypack/, create a package.json file with the name of the folder and a main javascript file with the same name, inside a ./lib/ directory.

    {
      "name" : "mypack",
      "main" : "./lib/mypack.js"
    }
    

    Now you can use require('./mypack') and node will load ./mypack/lib/mypack.js.

    However if you do not include this package.json file, it may still work. Without the file, node will attempt to load ./mypack/index.js, or if that's not there, ./mypack/index.node.

    My understanding is that this could be beneficial if you have split your program into many javascript files but do not want to concatenate them for deployment.

    0 讨论(0)
  • 2020-12-13 14:26

    You can use destructuring assignment to map an array of exported modules from require statements in one line:

    const requires = (...modules) => modules.map(module => require(module));
    const [fs, path] = requires('fs', 'path');
    
    0 讨论(0)
  • 2020-12-13 14:37

    I have a snippet of code that requires more than one module, but it doesn't clump them together as your post suggests. However, that can be overcome with a trick that I found.

    function requireMany () {
        return Array.prototype.slice.call(arguments).map(function (value) {
            try {
                return require(value)
            }
            catch (event) {
                return console.log(event)
            }
        })
    }
    

    And you use it as such

    requireMany("fs", "socket.io", "path")
    

    Which will return

    [ fs {}, socketio {}, path {} ]
    

    If a module is not found, an error will be sent to the console. It won't break the programme. The error will be shown in the array as undefined. The array will not be shorter because one of the modules failed to load.

    Then you can bind those each of those array elements to a variable name, like so:

    var [fs, socketio, path] = requireMany("fs", "socket.io", "path")
    

    It essentially works like an object, but assigns the keys and their values to the global namespace. So, in your case, you could do:

    var [foo, bar] = requireMany("./foo.js", "./bar.js")
    foo() //return "hello from one"
    bar() //return "hello from two"
    

    And if you do want it to break the programme on error, just use this modified version, which is smaller

    function requireMany () {
        return Array.prototype.slice.call(arguments).map(require)
    }
    
    0 讨论(0)
  • 2020-12-13 14:38

    I was doing something similar to what @freakish suggests in his answer with a project where I've a list of test scripts that are pulled into a Puppeteer + Jest testing setup. My test files follow the naming convention testname1.js - testnameN.js and I was able use a generator function to require N number of files from the particular directory with the approach below:

    const fs = require('fs');
    const path = require('path');
    
    module.exports = class FilesInDirectory {
    
        constructor(directory) {
    
            this.fid = fs.readdirSync(path.resolve(directory));
            this.requiredFiles = (this.fid.map((fileId) => {
                let resolvedPath = path.resolve(directory, fileId);
                return require(resolvedPath);
            })).filter(file => !!file);
    
        }
    
        printRetrievedFiles() {
            console.log(this.requiredFiles);
        }
    
        nextFileGenerator() {
    
            const parent = this;
            const fidLength = parent.requiredFiles.length;
    
            function* iterate(index) {
                while (index < fidLength) {
                    yield parent.requiredFiles[index++];
                }
            }
            return iterate(0);
        }
    
    }
    

    Then use like so:

    //Use in test
    const FilesInDirectory = require('./utilities/getfilesindirectory');
    const StepsCollection = new FilesInDirectory('./test-steps');
    const StepsGenerator = StepsCollection.nextFileGenerator();
    
    //Assuming we're in an async function
    await StepsGenerator.next().value.FUNCTION_REQUIRED_FROM_FILE(someArg);
    
    0 讨论(0)
提交回复
热议问题