常见前端名词

CommonJs

CommonJs 是一种 JavaScript 语言的模块化规范,它通常会在服务端的 Nodejs 上使用。项目是由多个模块组成的,模块和模块之间的调用,需要各个模块有相同规范的 API,这样一来在使用的过程中不会有那么多的学习成本,并且对于单个模块来说是类聚的。

在 CommonJs 的模块化规范中,每一个文件就是一个模块,拥有自己独立的作用域、变量、以及方法等,对其他的模块都不可见。CommonJS规范规定,每个模块内部,module 变量代表当前模块。这个变量是一个对象,它的 exports 属性(module.exports)是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。require 方法用于加载模块。

//moudle-a.js
moudle.exports = {
    a: 1
};

//moudle-b.js
var ma = require('./moudle-a');
var b = ma.a + 2;
module.exports ={
    b: b
};

模块化规范给项目带来极大的好处,在业务复杂,模块众多的大型项目中,开发者都遵循相同的规则来开发各自的模块,他们通过规范来约束模块的定义,大家不需要太多的沟通或者大量的文档来说明自己的模块使用规则,成千上万的模块就这样生产,并能够容易的使用。它的意义不仅是让模块看起来很规范,在合作开发、社区中传播中也起到了重大的作用。

CMD

CMD 叫做通用模块定义规范(Common Module Definiton),它是类似于 CommonJs 模块化规范,但是运行于浏览器之上的。它是随着前端业务和架构的复杂度越来越高运用而生的,来自淘宝玉伯的 SeaJS 就是它的实现。

CMD 规范尽量保持简单,并与 CommonJS 的 Modules 规范保持了很大的兼容性。通过 CMD 规范书写的模块,可以很容易在 Node.js 中运行。在 CMD 规范中,一个模块就是一个文件。格式如下:

define(factory);

具体用法如下:

// moudle-a.js
define(function(require, exports, module) {

    module.exports = { 
        a: 1 
    };

});

// moudle-b.js
define(function(require, exports, module) {

    var ma = require('./moudle-a');
    var b = ma.a + 2;
    module.exports = { 
        b: b 
    };

});

CMD 规范拥有简单、异步加载脚本、友好的调试并且兼容 Nodejs,它的确在开发过程中给我们提供了较好的模块管理方式。

AMD

AMD 叫做异步模块定义规范(Asynchronous Module Definition),它是 CommonJs 模块化规范的超集,但是运行于浏览器之上的。AMD 的特点就和它的名字一样,模块的加载过程是异步的,它大大的利用了浏览器的并发请求能力,让模块的依赖过程的阻塞变得更少了。requireJs 就是 AMD 模块化规范的实现。

AMD 作为一个规范,只需定义其语法 API,而不关心其实现。AMD 规范简单到只有一个 API,即 define 函数:

define(id?, dependencies?, factory);

具体用法如下:

// moudle-a.js
define('moudleA', function() { 
    return {
        a: 1
    }
});

// moudle-b.js
define(['moudleA'], function(ma) {
    var b = ma.a + 2;

    return {
        b: b
    }
});

UMD

UMD 叫做通用模块定义定义规范(Universal Module Definition)。也是随着大前端的趋势所诞生,他可以通过运行时或者编译时让同一个代码模块使用 CommonJS、CMD 甚至是 AMD 的项目中运行。未来同一个 JavaScript 包运行在浏览器端、服务器端甚至是 APP 端都只需要遵守同一个写法就行了。

它没有自己的规范,是集结了 CommonJS、CMD、AMD 的规范于一身,它的具体实现:

;((root, factory) => {
  if (typeof define === 'function' && define.amd) {
    //AMD
    define(['jquery'], factory)
  } else if (typeof exports === 'object') {
    //CommonJS
    var $ = requie('jquery')
    module.exports = factory($)
  } else {
    root.testModule = factory(root.jQuery)
  }
})(this, $ => {
  //todo
})

不难发现,他在定义模板的时候会检测当前使用环境和模块的定义方式,将各种模块化定义方式转化为同样一种写法。它的出现也是前端技术发展的产物,前端在实现跨平台的道路上不断的前进,UMD 规范将浏览器端、服务器端甚至是 APP 端都大统一了,当然它或许不是未来最好的模块化方式,未来在 ED6+、TypeScript、Dart 这些拥有高级语法的语言会代替这些方案。