也许这个问题有点傻,但是可以用一个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
答案 0 :(得分:31)
首先使用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();
答案 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');