JS 模块化的发展史(三)

167 阅读2分钟

「这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战」。

模块化的发展

由于CommonJS 的执行模式是同步的,在浏览器中同步的执行方式并不理想,于是在此之后又有两大规范的出现,他们分别是 AMD / CMD 。

AMD(异步模块定义)

AMD 即Asynchronous Module Definition,产出于 RequiresJS 对模块定义的规范产出,主要解决以下问题。

  1. 多个js文件可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器。
  2. js加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应时间越长。

采用异步方式加载,模块的加载不影响他后面的语句的运行,所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成以后,这个回调函数,才会运行。

我们看下面的一个使用实例。用definde()定义模块,用require()加载模块。

// 定义模块 myModule.js
define(['dependency'], function(){
    var name = 'Byron';
    function printName(){
        console.log(name);
    }

    return {
        printName: printName
    };
});

// 加载模块
require(['myModule'], function (my){
  my.printName();
});

CMD(通用模块定义)

CMD 即Common Module Definition通用模块定义,CMD 规范是国内发展出来的,就像 AMD 有requireJS,CMD有个浏览器的实现 SeaJS,SeaJS 要解决的问题和 requireJS 一样,只不过在模块定义方式和模块加(可以说运行、解析)时机上有所不同

CMD 模块定义方式

  1. define(id?, deps?, factory ) 是一个全局函数,用来定义模块
  2. define 接受 factory 参数,factory 可以是一个函数,也可以是一个对象或者字符串。当factory是对象或者字符串,代表该模块的接口就是对象,字符串。
  1. define 接受 id 参数, 作为模块标识。
  2. define 接受 deps 数组,作为模块依赖。
define({ "foo": "bar" });
define('I am a template. My name is {{name}}.');

define('a', ['jquery'], function(require, exports, module) {  // 模块代码});

CMD模块导入方式

  1. require 是一个方法,接受 模块标识 作为唯一参数,用来获取其他模块提供的接口。
  2. require.async 方法用来在模块内部异步加载模块,并在加载完成后执行指定回调。callback 参数可选
  1. require(id, callback) ,id 为模块的唯一标识,callback 为回调函数。
require.async(['./c', './d'], function(c, d) {
    c.doSomething();
    d.doSomething();
}

小结:

AMD 与 CMD 的最大区别在于,AMD 依赖前置,提前执行。CMD 依赖就近,延迟执行。