【问题标题】:Node.js, require all modules in folder and use loaded module directlyNode.js,需要文件夹中的所有模块并直接使用加载的模块
【发布时间】:2015-10-17 21:20:47
【问题描述】:

在 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 的部分。

但是,应谨慎使用全局变量。通过向全局空间添加模块,我降低了可测试性和封装性。但在这种情况下,我认为使用这种方法是可以接受的。

【问题讨论】:

标签: javascript node.js directory require


【解决方案1】:

它并不完美,但这样的事情应该可以帮助你完成这个:

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

【讨论】:

    【解决方案2】:

    第一件事...

    我相信您将 Node.js 与 PHP 或 .Net 混淆了,因为您没有将在其他模块中导出的内容“导入”到当前模块中。除非您手动执行此操作,否则不会。例如,当您调用时

    require('./my-module');
    

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

    您不会将内容加载到当前上下文中;您只需加载脚本而不将其分配给任何内容。要访问 my-module 公开的内容,您需要分配它,或者直接使用它。例如:

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

    或

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

    模块不是命名空间,而是在其自身上下文之外公开公共属性的 JavaScript 对象(即使用 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。

    【讨论】:

      猜你喜欢
      • 2018-08-10
      • 2016-02-26
      • 2010-11-06
      • 1970-01-01
      • 1970-01-01
      • 2018-09-24
      • 1970-01-01
      • 2012-03-22
      • 2014-05-30
      相关资源
      最近更新 更多