美文网首页饥人谷技术博客
前端模块化之旅(二):CommonJS、AMD和CMD

前端模块化之旅(二):CommonJS、AMD和CMD

作者: 西湖摸鱼闰土 | 来源:发表于2016-05-18 20:13 被阅读387次
前端模块化之旅二.jpg

继续前篇,各种模块化规范开始推出,其中比较突出的是服务器端的 CommonJS 规范,它是 Nood.JS 在实践中推出的,也是首先采用 JS 模块化概念的语言,跳出了浏览器;进而出现了浏览器环境的模块化方案 AMD和CMD。

CommonJS Modules/1.0

CommonJS 规范是服务器端的模块化的规范,是 Nood.js 在实践中推出的,Nood.js 也是首先采用 js 模块化的;

它规定一个单独的文件就是一个模块,一个模块中存在一个自由变量 require,这是个函数,用于加载模块:

  • 这个 require 函数接受一个模块标识符,返回外部模块所输出的 API;
  • 如果出现依赖闭环(dependency cycle),那么外部模块在被它的传递依赖(transitive dependencies)所 require 的时候可能并没有执行完成;在这种情况下,"require"返回的对象必须至少包含此外部模块在调用require函数(会进入当前模块执行环境)之前就已经准备完毕的输出。
  • 如果请求的模块不能返回,那么"require"必须抛出一个错误。

在一个模块中,会存在一个名为 exports 的自由变量,这是一个对象,模块可以在执行的时候把自身的API加入到其中,用于定义模块,导出给其他地方使用;

exports 对象是输出模块变量的唯一方式。

参照下面的一个例子:

//math.js
exports.add = function(a,b){
    var c = a + b;
    return c;
}

//index.js
var add = require('math').add;//
console.log(add(1,1));//2

math.js中将 add 函数绑定到模块中的 exports 对象中,之后在 index.js 模块中用 require 方法加载了 math.js 模块,并调用该模块中的 add 函数。

AMD

Asynchronous Module Definition,即异步的模块定义,是浏览器端的模块化规范,是 RequireJS 在推广过程中对模块定义的规范化产出。

与服务器端的模块化规范 CommonJS 不同,AMD 的模块加载是异步的,因为是浏览器端,所以势必要是异步的(浏览器同步加载模块会导致性能、可用性、调试和跨域访问等问题)。因为模块异步加载时不会影响后面程序的执行,前面总结过 js 异步的情况,依赖某些模块的语句均放置在回调函数中,等待模块加载完成后再执行;

AMD 规范只定义了一个函数 define ,是一个全局变量,如下定义一个模块的语法:

define(id?, dependencies?, factory);
  • id:模块的名字,如果没有提供该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字;

  • dependencies:模块的依赖,已被模块定义的模块标识的数组字面量。依赖参数是可选的,如果忽略此参数,它应该默认为 ["require", "exports", "module"]。然而,如果工厂方法的长度属性小于3,加载器会选择以函数的长度属性指定的参数个数调用工厂方法。

  • factory:模块的工厂函数,模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。

参照下面的一个例子:

define('myModule',['jQuery','types/Employee'],function($,Employee){//定义模块myModule,引入依赖jQuery,types/Employee
     function Programmer(){
            //do something
        };
        Programmer.prototype = new Employee();
        return Programmer;  //return Constructor
})

CMD

Common Module Definition,即通用模块定义,是浏览器端的模块化规范,是 SeaJS 在推广过程中对模块定义的规范化产出。

如下定义一个模块的语法:

define(factory)
  • factory 为函数时,表示是模块的构造方法。执行该构造方法,可以得到模块向外提供的接口。factory 方法在执行时,默认会传入三个参数:require、exports 和 module.

AMD 是依赖关系前置,提前执行;CMD 是类似于 CommonJS 那样 按需加载,延迟执行

//CMD recommanded
define(function(require, exports, module){
    var a = require('a');
    a.doSomething();
    var b = require('b');
    b.doSomething();    // 依赖就近,延迟执行
});

//AMD recommanded
define(['a', 'b'], function(a, b){
    a.doSomething();    // 依赖前置,提前执行
    b.doSomething();
});

明显看出和 AMD 不同,模块定义时已不用立马引入依赖,而是运行到需要时候再加载,根据顺序执行,这样更像是 CommonJS 的风格,让人感觉也像是同步加载似的。但实际上 CMD 内部处理是对文件做了一个词法的解析,在还没执行的时候,解析出所需的依赖,并不是真正的同步。


参考:

相关文章

  • Seajs使用实例入门介绍

    seajs是啥,可以看看这篇前端模块化(CommonJs,AMD和CMD)点我点我--项目源码地址:https:/...

  • 前端模块化

    什么是前端模块化? 前端为什么需要模块化? CommonJS、AMD、ES6、CMD区别是什么? 一、什么是模块化...

  • js模块化相关

    js模块化编程之彻底弄懂CommonJS和AMD/CMD!

  • 归档

    AMD、CMD、CommonJs、ES6的对比 他们都是用于在模块化定义中使用的,AMD、CMD、CommonJs...

  • JS模块化

    模块化规范:CommonJS,AMD,CMD,UMD,ES6 Module CommonJS CommonJS是服...

  • 前端模块化之旅(二):CommonJS、AMD和CMD

    继续前篇,各种模块化规范开始推出,其中比较突出的是服务器端的 CommonJS 规范,它是 Nood.JS 在实践...

  • 通过 babel 体验 ES6 模块化

    原文: 一篇理解前端模块化:AMD、CMD、CommonJS、ES6[https://mp.weixin.qq.c...

  • css,js(2)

    1.0AMD CMD CommonJS /* AMD是RequireJS对模块化的定义 * CMD是seaJS对模...

  • ES6模块化

    模块化技术有哪些:- CommonJS(nodejs)、ES6模块化、AMD、CMD等 CommonJS:Comm...

  • 前端模块化(CommonJs,AMD和CMD)

    前端模块规范有三种:CommonJs,AMD和CMD。CommonJs用在服务器端,AMD和CMD用在浏览器环境A...

网友评论

    本文标题:前端模块化之旅(二):CommonJS、AMD和CMD

    本文链接:https://www.haomeiwen.com/subject/txbwrttx.html