Node.js,需要文件夹中的所有模块并直接使用加载的模块
Node.js, require all modules in folder and use loaded module directly
在MyModule文件夹中,我有这两个JS文件。
SayHello.js
module.exports.SayHello = function() {
return('Hello !');
}
SayByeBye.js
module.exports.SayByeBye = function() {
return('Bye Bye!');
}
在 Node.js 中,我想获取 MyModule 文件夹中的所有文件并直接调用函数 SayHello
& SayByeBye
,例如:
require(./MyModule)
console.log(SayHello());
console.log(SayByeBye());
编辑:
有了@Yanick Rochon的回答,我这样做了:
>./app/my-module/index.js
global.SayHello = require('./my-module/SayHello').SayHello;
global.SayByeBye = require('./my-module/SayByeBye').SayByeBye;
> ./app/my-module/say-hello.js
module.exports.SayHello = function() {
return('Hello !');
};
> ./app/my-module/say-byebye.js
module.exports.SayByeBye = function() {
return('Bye Bye !');
};
>./app/main.js
require('./my-module');
console.log(SayHello());
console.log(SayByeBye());
节点文档中有一个关于 global objects 的部分。
但是,应谨慎使用全局变量。通过向全局 space 添加模块,我降低了可测试性和封装性。但是在这种情况下,我觉得用这个方法是可以接受的。
它并不完美,但像这样的东西应该可以帮助你完成这个:
var fs = require('fs');
var path = require('path');
var files = fs.readdirSync(__dirname);
var ownFilename = __filename.substr(__filename.lastIndexOf(path.delimiter) + 1);
var modules = {};
for (var i = 0; i < files.length; i++) {
var filename = files[i];
if (filename.substr(-3) === '.js' && filename !== ownFilename) {
modules[filename.slice(0, -3)] = require('./' + filename);
}
}
console.log(modules.SayByeBye());
console.log(modules.SayHello());
第一件事...
我认为您将 Node.js 误认为是 PHP 或 .Net,因为您没有 "import" 进入当前模块,而其他模块导出的内容。除非您手动执行,否则不会。例如,当您调用
require('./my-module');
(请注意,我将您的 MyModule
重命名为 Node.js 命名约定。)
您不会将内容加载到当前上下文中;您只需加载脚本而不将其分配给任何东西。要访问 my-module
公开的内容,您需要分配它或直接使用它。例如:
require('./my-module').someFunction();
或
var myModule = require('./my-module');
myModule.someFunction();
模块不是命名空间,而是 JavaScript 对象,它在自身上下文之外公开 public 属性(即使用 module.exports = ...
)
回答
您有两种最流行的方法来完成此任务:
解决方案 1
在您要加载所有脚本的文件夹中创建一个 index.json
文件。返回的JSON对象应该是自动加载的所有模块:
> ./app/index.json
[
"say-hello.js",
"say-goodbye.js"
]
您还应该考虑让所有文件 API 兼容 :
> ./app/say-hello.js
module.exports = function sayHello() {
return 'Hello !';
};
> ./app/say-goodbye.js
module.exports.sayGoodbye = function () {
return 'Goodbye !';
};
然后像这样加载并执行所有内容:
var path = require('path');
var basePath = './app/';
var files = require(basePath);
var mods = files.forEach(function (loaded, file) {
var mod = require(path.join(basePath, file));
// mod is a function with a name, so use it!
if (mod instanceof Function) {
loaded[mod.name] = mod;
} else {
Object.keys(mod).forEach(function (property) {
loaded[property] = mod.property;
});
}
}, {});
mods.sayHello();
mods.sayGoodbye();
解决方案 2
读取文件夹中的所有 .js
文件并导入它们。我强烈建议您为此使用 glob
。
var glob = require("glob")
var path = require('path');
var basePath = './app/';
var mods = glob.sync(path.join(basePath, '*.js')).reduce(function (loaded, file) {
var mod = require(file);
// mod is a function with a name, so use it!
if (mod instanceof Function) {
loaded[mod.name] = mod;
} else {
Object.keys(mod).forEach(function (property) {
loaded[property] = mod.property;
});
}
return loaded;
}, {});
mods.sayHello();
mods.sayGoodbye();
注意module.exports
和exports
的区别
一般module.exports === exports
,但建议使用module.exports
,原因如下
exports = function Foo() { } // will not do anything
module.exports = function Foo() { } // but this will do what you expect
// however these two lines produce the same result
exports.foo = 'Bar';
module.exports.foo = 'Bar';
因此,在所有情况下都建议 module.exports
。
在MyModule文件夹中,我有这两个JS文件。
SayHello.js
module.exports.SayHello = function() {
return('Hello !');
}
SayByeBye.js
module.exports.SayByeBye = function() {
return('Bye Bye!');
}
在 Node.js 中,我想获取 MyModule 文件夹中的所有文件并直接调用函数 SayHello
& SayByeBye
,例如:
require(./MyModule)
console.log(SayHello());
console.log(SayByeBye());
编辑:
有了@Yanick Rochon的回答,我这样做了:
>./app/my-module/index.js
global.SayHello = require('./my-module/SayHello').SayHello;
global.SayByeBye = require('./my-module/SayByeBye').SayByeBye;
> ./app/my-module/say-hello.js
module.exports.SayHello = function() {
return('Hello !');
};
> ./app/my-module/say-byebye.js
module.exports.SayByeBye = function() {
return('Bye Bye !');
};
>./app/main.js
require('./my-module');
console.log(SayHello());
console.log(SayByeBye());
节点文档中有一个关于 global objects 的部分。
但是,应谨慎使用全局变量。通过向全局 space 添加模块,我降低了可测试性和封装性。但是在这种情况下,我觉得用这个方法是可以接受的。
它并不完美,但像这样的东西应该可以帮助你完成这个:
var fs = require('fs');
var path = require('path');
var files = fs.readdirSync(__dirname);
var ownFilename = __filename.substr(__filename.lastIndexOf(path.delimiter) + 1);
var modules = {};
for (var i = 0; i < files.length; i++) {
var filename = files[i];
if (filename.substr(-3) === '.js' && filename !== ownFilename) {
modules[filename.slice(0, -3)] = require('./' + filename);
}
}
console.log(modules.SayByeBye());
console.log(modules.SayHello());
第一件事...
我认为您将 Node.js 误认为是 PHP 或 .Net,因为您没有 "import" 进入当前模块,而其他模块导出的内容。除非您手动执行,否则不会。例如,当您调用
require('./my-module');
(请注意,我将您的 MyModule
重命名为 Node.js 命名约定。)
您不会将内容加载到当前上下文中;您只需加载脚本而不将其分配给任何东西。要访问 my-module
公开的内容,您需要分配它或直接使用它。例如:
require('./my-module').someFunction();
或
var myModule = require('./my-module');
myModule.someFunction();
模块不是命名空间,而是 JavaScript 对象,它在自身上下文之外公开 public 属性(即使用 module.exports = ...
)
回答
您有两种最流行的方法来完成此任务:
解决方案 1
在您要加载所有脚本的文件夹中创建一个 index.json
文件。返回的JSON对象应该是自动加载的所有模块:
> ./app/index.json
[
"say-hello.js",
"say-goodbye.js"
]
您还应该考虑让所有文件 API 兼容 :
> ./app/say-hello.js
module.exports = function sayHello() {
return 'Hello !';
};
> ./app/say-goodbye.js
module.exports.sayGoodbye = function () {
return 'Goodbye !';
};
然后像这样加载并执行所有内容:
var path = require('path');
var basePath = './app/';
var files = require(basePath);
var mods = files.forEach(function (loaded, file) {
var mod = require(path.join(basePath, file));
// mod is a function with a name, so use it!
if (mod instanceof Function) {
loaded[mod.name] = mod;
} else {
Object.keys(mod).forEach(function (property) {
loaded[property] = mod.property;
});
}
}, {});
mods.sayHello();
mods.sayGoodbye();
解决方案 2
读取文件夹中的所有 .js
文件并导入它们。我强烈建议您为此使用 glob
。
var glob = require("glob")
var path = require('path');
var basePath = './app/';
var mods = glob.sync(path.join(basePath, '*.js')).reduce(function (loaded, file) {
var mod = require(file);
// mod is a function with a name, so use it!
if (mod instanceof Function) {
loaded[mod.name] = mod;
} else {
Object.keys(mod).forEach(function (property) {
loaded[property] = mod.property;
});
}
return loaded;
}, {});
mods.sayHello();
mods.sayGoodbye();
注意module.exports
和exports
的区别
一般module.exports === exports
,但建议使用module.exports
,原因如下
exports = function Foo() { } // will not do anything
module.exports = function Foo() { } // but this will do what you expect
// however these two lines produce the same result
exports.foo = 'Bar';
module.exports.foo = 'Bar';
因此,在所有情况下都建议 module.exports
。