我可以使用一个require语句加载多个文件吗?

时间:2012-05-11 15:22:18

标签: node.js

也许这个问题有点傻,但是可以用一个require语句加载多个.js文件吗?像这样:

var mylib = require('./lib/mylibfiles');

并使用:

mylib.foo(); //return "hello from one"

mylib.bar(): //return "hello from two"

在文件夹中,mylibfiles将有两个文件:

One.js

exports.foo= function(){return "hello from one";}

Two.js

exports.bar= function(){return "hello from two";}

我正在考虑将package.json放在要加载所有文件的文件夹中,但我不知道如何。我想的其他方法是有一个index.js再次导出所有东西,但我会重复工作。

谢谢!

P.D:我在Windows 7机器上使用nodejs v0.611

5 个答案:

答案 0 :(得分:31)

首先使用require不会重复任何内容。它加载模块并且缓存,因此再次调用require将从内存中获取它(因此您可以在不与源代码交互的情况下修改模块 - 这有时是可取的,对于例如,当你想在模块中存储数据库连接时。)

此外,package.json不会加载任何内容,也不会与您的应用完全互动。它仅用于npm

现在您不能同时需要多个模块。例如,如果One.jsTwo.js都定义了具有相同名称的函数,会发生什么?还有更多问题。

但你可以做的是写下额外的文件,比如说modules.js,内容如下

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

然后你可以简单地使用

var modules = require('./modules.js');
modules.one.foo();
modules.two.bar();

答案 1 :(得分:2)

是的,根据node docs,您可能需要文件夹作为模块。我们假设你想要一个名为./mypack/的文件夹。

./mypack/内,在package.json目录中创建一个name文件,其中包含main文件夹和./lib/ javascript文件,名称相同

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

现在您可以使用require('./mypack'),节点将加载./mypack/lib/mypack.js

但是,如果您不包含此package.json文件,它可能仍然有效。如果没有该文件,节点将尝试加载./mypack/index.js,或者如果不存在,./mypack/index.node

我的理解是,如果您将程序拆分为许多javascript文件但又不想将它们连接起来进行部署,这可能会有所帮助。

答案 2 :(得分:1)

我有一段需要多个模块的代码,但它并没有像你的帖子所说的那样将它们聚集在一起。但是,我可以通过一个技巧来解决这个问题。

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

你可以这样使用

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

将返回

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

如果找不到模块,则会向控制台发送错误。它不会打破这个计划。该错误将在数组中显示为undefined。该阵列不会更短,因为其中一个模块无法加载。

然后,您可以将每个数组元素绑定到变量名称,如下所示:

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

它本质上就像一个对象,但是将键及其值分配给全局命名空间。所以,在你的情况下,你可以这样做:

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

如果您确实希望它在出错时破坏程序,只需使用此修改版本,即较小的

function requireMany () {
    return Array.prototype.slice.call(arguments).map(require)
}

答案 3 :(得分:0)

我在一个项目中执行了与@freakish在his answer中建议的类似操作,在该项目中,我列出了一系列测试脚本,这些脚本已放入Puppeteer + Jest测试设置中。我的测试文件遵循命名约定testname1.js-testnameN.js,并且可以使用生成器功能通过以下方法从特定目录中请求N个文件:

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

}

然后像这样使用:

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

答案 4 :(得分:0)

您可以使用destructuring assignment在一行中映射从require语句导出的模块数组:

const requires = (...modules) => modules.map(module => require(module));
const [fs, path] = requires('fs', 'path');