Node.js,要求文件夹中的所有模块直接使用加载的模块

MyModule文件夹中,我有这两个JS文件。

SayHello.js

module.exports.SayHello = function() { return('Hello !'); } 

SayByeBye.js

 module.exports.SayByeBye = function() { return('Bye Bye!'); } 

在Node.js中,我想要求MyModule文件夹中的所有文件,并直接调用SayHelloSayByeBye函数:

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

节点文档中有关于全局对象的一节。

但是,应该谨慎使用全局variables。 通过向全局空间添加模块,我减less了可testing性和封装。 但在这种情况下,我认为使用这种方法是可以接受的。

第一件事…

我相信你错误的使用PHP或.Net的Node.js,在这个意义上,你不会“导入”到其他模块中导出到当前模块。 除非你手动去做。 例如,当你打电话

 require('./my-module'); 

(请注意,我将您的MyModule重命名为Node.js命名约定。)

你不会把事情加载到当前的上下文中; 你只是加载脚本,不要把它分配给任何东西。 要访问my-module公开的内容,您需要指定它,或者直接使用它。 例如 :

 require('./my-module').someFunction(); 

要么

 var myModule = require('./my-module'); myModule.someFunction(); 

模块不是名称空间,而是在公共属性之外公开属性的JavaScript对象(即使用module.exports = ...

回答

你有两种最stream行的方法来实现这一点:

解决scheme1

在要加载所有脚本的文件夹中创build一个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(); 

解决scheme2

阅读文件夹内的所有.js文件并导入它们。 我强烈build议你为此使用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.exportsexports之间的区别

通常module.exports === exports ,但是由于以下原因,build议使用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

这不是完美的,但是这样的事情应该可以帮助你实现这个目标:

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