模块化模块化

JS模块化初探-CommonJs、AMD、CMD和Requist

2017-07-16  本文已影响169人  放风筝的小小马

什么是模块化?

简单理解:将各个功能封装为独立的模块,当需要某个功能时,只需要加载相应的模块即可

为什么出现模块化?

随着技术的发展,web应用的代码日益增大,由于JavaScript的语言特性(在ES5之前js并没有像java一样拥有类和模块的语言等特性),导致其无法驾驭规模如此大的代码,因此迫切需要通过一种方式来模拟出类似于模块的功能,所以便出现了模块化

模块化的价值

没有出现模块化时,代码存在的问题

注意: 到这里时查看前端模块化开发的价值这篇文章

CommonJS、AMD和CMD

一个模块就是实现特定功能的文件,有了模块,我们就可以更方便地使用别人的代码,想要什么功能,就加载什么模块。模块开发需要遵循一定的规范,各行其是就都乱套了,由此便出现了CommonJS、AMD、CMD等规范(注意:这些都是规范,规范的作用是让人来遵守的,因此出现了很多支持这些规范的工具)

注意:到这里时,阅读以下文章了解下这三者之间的关系:

CommonJS介绍

阅读这篇文章:
CommonJS规范
目标:

注意:

Node应用由模块组成,采用CommonJS模块规范。
规范特点:

语法特点

代码示例

// 模块定义 myModel.js

var name = 'Byron';
function printName(){
    console.log(name);
}
function printFullName(firstName){
    console.log(firstName + name);
}
module.exports = {
    printName: printName,
    printFullName: printFullName
}

// 在其他文件中加载模块
var nameModule = require('./myModel.js');
nameModule.printName();

AMD规范

AMD 即 Asynchronous Module Definition异步模块定义),它是一个在浏览器端进行模块化开发的规范

因为该规范不是JavaScript原生支持的,因此使用该规范进行开发时,需要用到对应的库函数,如:RequireJS

RequireJS主要解决两个问题:

语法

定义模块
AMD规范定义了define()函数,它是一个全局变量,用于定于模块,语法:
define(id?, dependencies?, factory);

加载模块
在页面上使用require()函数加载模块,语法:
require([dependencies], function(){});
requiire接收两个参数:

  1. 第一个参数是一个数组,表示所依赖的模块
  2. 第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数的形式传入该函数,从而在函数内部就可以使用这些模块
    注意: require()函数在加载依赖的模块时是异步加载的,这样浏览器不会失去响应,它指定的回调函数,只有前面的模块加载完成后才会执行,*解决了依赖问题

例子

// 定义一个myModule.js模块
define(['dependency1', 'dependency2'], function(){
  var name = 'hexon';
  function sayName(){
    console.log(name);
  }
  return {
    sayName: sayName
  };
});

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

示例解析

参考文章:AMD (中文版):

AMD规范与CommonJS规范的兼容性

CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。

AMD规范使用define方法定义模块,下面就是一个例子:

define(['package/lib'], function(lib){
  function foo(){
    lib.log('hello world!');
  }

  return {
    foo: foo
  };
});

AMD规范允许输出的模块兼容CommonJS规范,这时define方法需要写成下面这样:

define(function (require, exports, module){
  var someModule = require("someModule");
  var anotherModule = require("anotherModule");

  someModule.doTehAwesome();
  anotherModule.doMoarAwesome();

  exports.asplode = function (){
    someModule.doTehAwesome();
    anotherModule.doMoarAwesome();
  };
});

CMD规范

CMD即Common Module Definition通用模块定义,CMD规范是国内发展而来的,CMD的代表库有SeaJS,SeaJS要解决的问题和RequireJS一样,只不过在模块定义方式和模块加载时机上有所不同,SeaJS是需要时才去加载,而RequireJS是预先加载好
语法
SeaJS推崇一个模块一个文件,遵循统一写法,使用define关键字定义一个模块
define
define(factory)

Module Context

define(function(require, exports, module) {

  // The module code goes here

});

示例代码
A typical sample

math.js

define(function(require, exports, module) {
  exports.add = function() {
    var sum = 0, i = 0, args = arguments, l = args.length;
    while (i < l) {
      sum += args[i++];
    }
    return sum;
  };
});

increment.js

define(function(require, exports, module) {
  var add = require('math').add;
  exports.increment = function(val) {
    return add(val, 1);
  };
});

program.js

define(function(require, exports, module) {
  var inc = require('increment').increment;
  var a = 1;
  inc(a); // 2

  module.id == "program";
});

参考:CMD介绍

上一篇 下一篇

猜你喜欢

热点阅读