30

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

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

并使用:

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

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

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

一个.js

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

二.js

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

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

谢谢!!

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

4

5 回答 5

46

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

package.json不会加载任何东西,并且根本不会与您的应用程序交互。它仅用于npm.

现在你不能一次需要多个模块。例如,如果两者都定义了同名的函数会发生One.js什么Two.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();
于 2012-05-11T15:35:43.840 回答
4

我有一段代码需要多个模块,但它并没有像您的帖子所建议的那样将它们聚集在一起。然而,这可以通过我发现的一个技巧来克服。

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 {} ]

如果未找到模块,则会将错误发送到控制台。它不会破坏程序。错误将在数组中显示为未定义。数组不会因为其中一个模块未能加载而变短。

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

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)
}
于 2016-09-01T02:51:01.710 回答
2

是的,根据节点文档,您可能需要一个文件夹作为模块。假设您想要 require() 一个名为../mypack/

在里面./mypack/,在一个目录中创建一个package.json包含文件name夹的文件和一个main同名的 javascript 文件./lib/

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

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

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

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

于 2015-02-28T23:33:52.293 回答
2

您可以使用解构赋值require从一行中的语句映射一组导出的模块:

const requires = (...modules) => modules.map(module => require(module));
const [fs, path] = requires('fs', 'path');
于 2020-06-26T23:16:06.360 回答
0

我正在做的事情类似于@freakish 在他的回答中建议的一个项目,其中我有一个测试脚本列表,这些脚本被拉入 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);
于 2019-06-26T13:47:07.417 回答