node中commonJs规范的实现原理

模块

node中的每个js文件,每个依赖都是一个模块,大大的提高了代码的可维护性,可避免每个模块间变量和函数的冲突。

模块采用的规范是commonJs规范。

模块原理如下:
这个也很容易实现,Node可以先准备一个对象module:

var module = {
  id:'hello',
  exports:{}
}

var load = function(module){
    function greet(name){
        console.log(name)
    }
    module.exports = greet;
    return modul.exports;
}

var exported = load(module)

save(modul,exported);

可见,变量module是Node在加载js文件前准备的一个变量,并将其传入加载函数,我们在hello.js中可以直接使用变量module原因就在于它实际上是函数的一个参数:

var greet = require('./hello');

module.exports vs exports

很多时候,你会看到,在Node环境中,有两种方法可以在一个模块中输出变量:

方法一:对module.exports赋值:

function hello() {
    console.log('Hello, world!');
}

function greet(name) {
    console.log('Hello, ' + name + '!');
}

module.exports = {
    hello: hello,
    greet: greet
};

方法二:直接使用exports:

// hello.js

function hello() {
    console.log('Hello, world!');
}

function greet(name) {
    console.log('Hello, ' + name + '!');
}

function hello() {
    console.log('Hello, world!');
}

exports.hello = hello;
exports.greet = greet;

其实这两个是同一变量

var module = {
    id: 'hello',
    exports: {}
};

var load = function (exports, module) {
    // hello.js的文件内容
    ...
    // load函数返回:
    return module.exports;
};

var exported = load(module.exports, module);

结论:
如果要输出一个键值对象{},可以利用exports这个已存在的空对象{},并继续在上面添加新的键值;

如果要输出一个函数或数组,必须直接对module.exports对象赋值。

所以我们可以得出结论:直接对module.exports赋值,可以应对任何情况

你可能感兴趣的:(node中commonJs规范的实现原理)