这两个module.exports有什么区别?

时间:2016-08-17 13:57:36

标签: javascript node.js commonjs

所以第一个就是:

myFile.js

var name = "Peter";

module.exports.sayHello = function () {
  console.log('Hello ' + name);
}

第二个

myFile.js

module.exports = function () {

  var name = 'Mary';

  function sayHello () {
    console.log('Hello ' + name);
  }

  return {
    sayHello : sayHello
  };

}();

基本上它是一样的吗?如果没有,有什么区别,每种方法的优缺点是什么?

4 个答案:

答案 0 :(得分:2)

对我而言,这是一回事。

也许第一个例子更常见。

您可以根据代码的其余部分使用两者。

答案 1 :(得分:2)

是的,它们基本相同。你不需要第二个例子的冗长。

在第一个示例中,您将向node.js注入的现有module.exports对象添加命名属性,在第二个示例中,您将覆盖原始对象 - 消费端没有区别。< / p>

答案 2 :(得分:2)

为什么我们需要模块?

如果您有这样的代码:

// module 1
var a = 1;
var x = function (){
    return a;
};

// module 2
var a = 2; // duplicated variable declaration
var y = function (){
    return a;
};

// main
console.log(x()); // BUG: this should read value from module 1 instead of module 2
console.log(y());

由于a变量已由第一个模块采用,因此会导致错误。你需要以某种方式定义模块。

使用前缀

通过旧式程序编程,您可以为单独的模块添加前缀:

// module 1
var m1_a = 1;
var m1_x = function (){
    return m1_a;
};

// module 2
var m2_a = 2;
var m2_y = function (){
    return m2_a;
};

// main
console.log(m1_x());
console.log(m2_y());

但这会降低代码的可读性。

使用闭包

通过javascript你有闭包,这让事情变得更容易一些:

// module 1
var x = (function (){
    var a = 1;
    var x = function (){
        return a;
    };
    return x;
})();

// module 2
var y = (function (){
    var a = 2;
    var y = function (){
        return a;
    };
    return y;
})();

// main
console.log(x());
console.log(y());

但是你仍然在一个文件中有不同的模块,因此该文件将非常庞大且难以维护。

使用node.js模块加载器

通过node.js,您可以将不同模块的代码移动到单独的文件中,因此可以很容易地维护不同模块的代码,因为您将能够更快地找到代码的相关部分:

m1.js

var a = 1;
var x = function (){
    return a;
};
module.exports = x;

m2.js

var a = 2;
var y = function (){
    return a;
};
module.exports = y;

main.js

var x = require("m1");
var y = require("m2");

console.log(x());
console.log(y());

您可以在浏览器中执行相同的操作

到目前为止我能提出的最简单的node.js样式浏览器模块加载器是:

var cache = {};

function require(name){
    if (name in cache)
        return cache[name];
    var uri = "./" + name + ".js";
    var xhr = new XMLHttpRequest();
    xhr.open("GET", uri, false);
    xhr.send(null);
    var moduleCode = xhr.responseText;
    var fn = new Function("module", moduleCode);
    var module = {};
    fn(module);
    cache[name] = module.exports;
    return cache[name];
};

OFC。使用browserify,webpack,require.js和其他更复杂的库更安全,我只想告诉你,编写一个加载器并不难。

我们从这一切中学到了什么?

node.js模块和闭包都用于模块化。你不应该混淆它们,因为它们解决了同样的问题,混合它们只会导致混乱!

答案 3 :(得分:1)

  

让我们来看看NodeJS中模块机制的基础知识。对于每一个JS   文件的基础现实发生在文件的顶部:

var exports = module.exports = {};
  
      
  1. 每当我们尝试获取导入时,它都会检索 module.exports
  2.   
  3. 如果我们在Js文件中同时执行
  4.   
 exports.key = "key1" and module.exports = {key : "VAL"}
  

根据规则在导入期间仅提取module.exports。

     

现在回到你的问题添加module.exports.sayHello会   添加{}的引用,这也是exports变量常见的。

     

但是,如果你这样做

 module.exports = function () {} // some function
  

它打破了链,它只分配给module.exports而不是   出口变量。

     

这就是为什么我们通过添加任何键来导出变量的原因   导入过程中的module.exports!希望它澄清!   关于这个https://www.sitepoint.com/understanding-module-exports-exports-node-js/

的一篇非常好的文章