Node.js,要求文件夹中的所有模块直接使用加载的模块
在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());
节点文档中有关于全局对象的一节。
但是,应该谨慎使用全局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.exports
和exports
之间的区别
通常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());