JavaScript模块化规范commonJs、AMD、CMD

一、CommonJS

CommonJS 原来叫 ServerJS,是以在浏览器环境之外构建 JavaScript 生态系统为目标而产生的项目,比如在服务器
和桌面环境中。
CommonJS 规范是为了解决 JavaScript 的作用域问题而定义的模块形式,可以使每个模块它自身的命名空间中执行。
该规范的主要内容是,模块必须通过 module.exports 导出对外的变量或接口,通过 require() 来导入其他模块的输出到当前模块作用域中。例子如下:

// moduleA.js
module.exports = function(x) {
    return x * x; 
};
// moduleB.js
const moduleA = require('./moduleA');
var result = moduleA(2);

CommonJS 是同步加载模块。

NodeJs就是采用commonJs规范。

二、AMD

AMD(Asynchronous Module Definition)(异步模块定义)是为浏览器环境设计的,因为 CommonJS 模块系统是同步加载的,当前浏览器环境还没有准备好同步加载模块的条件。
AMD 定义了一套 JavaScript 模块依赖异步加载标准,来解决同步加载的问题。
模块通过 define 函数定义在闭包中,格式如下:

define(id?: String, dependencies?: String[], factory: Function|Object);

id 是模块的名字,它是可选的参数。
dependencies 指定了所要依赖的模块列表,它是一个数组,也是可选的参数,每个依赖的模块的输出将作为参数一次传入 factory 中。如果没有指定 dependencies,那么它的默认值是 [“require”, “exports”, “module”]。

define(function(require, exports, module) {})

factory 是最后一个参数,它包裹了模块的具体实现,它是一个函数或者对象。如果是函数,那么它的返回值就是模块的输出接口或值。
定义一个名为 moduleA 的模块,它依赖 jQuery 模块:

define('moduleA', ['jquery'], function($) {
    // $ 是 jquery 模块的输出
    $('body').text('hello world');
});
// 使用
define(['moduleA'], function(moduleA) {});

RequireJS就是采用AMD规范。

三、CMD

CMD(Common Module Definition),在 CMD 规范中,一个模块就是一个文件。
代码的书写格式如下:

define(factory);

define是全局函数,用来定义模块。define接收factory参数,factory可以是函数,对象或字符串。
factory为对象或字符串时,表示该模块的接口就是该对象或字符串,比如要定义一个json数据模块:

define({"key" : "val"});

也可以通过字符串定义模板模块:

define("Hello {{name}}!")

factory是函数时,表示是模块的构造方法。执行该构造方法,可以得到模块对外提供的接口,factory方法在执行时,默认会传入三个参数,require,exports,module。

define(function(require, exports, module) {
    // 需要导出的模块
});

require是方法,接收模板标识作为唯一参数,用来获取其他模块提供的接口:

define(function(require, exports) {
    const a = require('./a');
    a.doSomething();
});

require是同步往下执行的,require.async(id, callback?)用来在模块内部异步加载模块,并在加载完后执行回调函数:

define(function(require, exports) {
    require.async(['./a', './b'], function(c, d) {
        c.doSomething();
        d.doSomething();
    });
});

factory是函数时的第二个参数exports,exports是一个对象,用来对外提供模块接口。

define(function(require, exports) {
    exports.str = 'xxxxx';  // 对外提供str属性

    exports.doSomething = function() {  // 对外提供 doSomething() 方法
        // TODO
    };
});

除了exports外,还可以用return直接对外提供对象接口

define(function(require, exports) {
    return {
        str : 'xxxxx' ,
        doSomething : function() {}
    };
});

exports是module.exports对象的一个引用,很多时候exports都无法满足要求,例如对外提供一个实例对象:

define(function(require, exports, module) {
    function Person(name, age) {
        this.name = name;
        this.age = age;
    }
    module.exports = new Person('lily', 20); // 对外提供实例化后的Person对象。
});

module.exports还可以对外提供一个函数(exports不可以):

define(function(require, exports, module) {
    var Person = function(name, age) {
        this.name = name;
        this.age = age;
    }
    module.exports = Person; // 对外提供Person函数。
});

sea.js就是采用CMD规范。

四、AMD+CMD比较

AMD默认是依赖前置,在一开始就将需要依赖的文件配置并加载好:

define('moduleA', ['jquery'], function($) {
    // 依赖的配置文件已经配置并加载好了。
    $('body').text('hello world');
});

CMD是依赖就近,需要使用的时候才会去配置加载:

define(function(require, exports) {
    var a = require('./a.js'); // 配置并加载,同步

    if(false) {
        var b = require('./b.js'); // 该配置的文件永远不会去加载,
    }
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值