AMD、CMD规范、Sea.js使用

为什么要模块化

  1. 解决命名冲突
  2. 绝交繁琐的文件依赖
  3. 可读性、可维护性

参考这里

// foobar.js
//私有变量
var test = 123;

//公有方法
function foobar () {

    this.foo = function () {
        // do someing ...
    }
    this.bar = function () {
        //do someing ...
    }
}

//exports对象上的方法和变量是公有的
var foobar = new foobar();
exports.foobar = foobar;

//require方法默认读取js文件,所以可以省略js后缀
var test = require('./boobar').foobar;

test.bar();

模块化规范

AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。

CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。

类似的还有 CommonJS Modules/2.0 规范。

这些规范的目的都是为了 JavaScript 的模块化开发,特别是在浏览器端的。目前这些规范的实现都能达成浏览器端模块化开发的目的。

AMD规范(Asynchromous Module Definition)

AMD 是 RequireJS 在推广过程中对模块定义的规范化产出

AMD异步加载模块。它的模块支持对象 函数 构造器 字符串 JSON等各种类型的模块。

适用AMD规范适用define方法定义模块,用require加载模块。

define定义模块

// 这里的 module_id(myModule)仅作为示例使用

define('myModule', 
    ['math', 'graph'], 
    function ( math, graph ) {
        return {
            plot: function(x, y){
                return graph.drawPie(math.randomGrid(x,y));
            }
        }
    };
});

require加载模块

require(['foo', 'bar'], function ( foo, bar ) {
    // 这里写其余的代码
    foo.doSomething();
});

CMD规范

CMD是SeaJS 在推广过程中对模块定义的规范化产出,参考这里

1.define 是一个全局函数,用来定义模块。

define(function(require, exports, module) {

  // 模块代码

});

2.require 是一个方法,接受 模块标识 作为唯一参数,用来获取其他模块提供的接口。

define(function(require, exports) {
  // 获取模块 a 的接口
  var a = require('./a');
  // 调用模块 a 的方法
  a.doSomething();
});

3.require.async 方法用来在模块内部异步加载模块,并在加载完成后执行指定回调。callback 参数可选。

define(function(require, exports, module) {
  // 异步加载一个模块,在加载完成时,执行回调
  require.async('./b', function(b) {
    b.doSomething();
  });

  // 异步加载多个模块,在加载完成时,执行回调
  require.async(['./c', './d'], function(c, d) {
    c.doSomething();
    d.doSomething();
  });

});

4.exports 是一个对象,用来向外提供模块接口。

define(function(require, exports) {

  // 对外提供 foo 属性
  exports.foo = 'bar';

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

});

//除了给 exports 对象增加成员,还可以使用 return 直接向外提供接口。
define(function(require) {
  // 通过 return 直接提供接口
  return {
    foo: 'bar',
    doSomething: function() {}
  };
});

5.module 是一个对象,上面存储了与当前模块相关联的一些属性和方法。

define(function(require, exports, module) {
    console.log(module.uri);
    module.exports = {
        foo: 'bar',
        doSomething: function() {}
    };
});

AMD规范与CMD规范区别参考这里

Sea.js

1.加载sea.js文件 屏幕快照 2015-02-11 下午6.30.38

<script src="js/lib/sea.js"></script>
<script type="text/javascript">

    seajs.config({
      base: "./js",  
      alias: {
        "jquery": "./lib/jquery-1.11.2.min.js"
      }
    });

    // 加载入口模块
    seajs.use("main.js");
</script>

2.配置seajs配置项

base是根路径,以后的模块加载都是相对于当前路径 alias是依赖项目,相当于指定额外的具体路径。

3.执行seajs.use("main")。相当于执行 ./js/main.js

4.main模块

//main.js
define("main",  function(require) {
    var ToTop = require("to-top"),  //模块用require加载,模块名称等于文件名
        StickUp = require("stick-up"),
        LazyLoad = require("lazy-load");

    console.log(ToTop);
    ToTop.toTop.init();
    StickUp.init();
    console.log(LazyLoad);
    LazyLoad.init();
});

5.其他模块

//直接把模块return
define("lazy-load",['jquery'], function(require){

    var $ = require('jquery');
    console.log($);
    var lazyLoad = {
        //...
    };

    return lazyLoad;
});

//把模块赋值倒module.exports相当于return出去
define('stick-up',['jquery'], function(require, exports, module){

    var $ = require('jquery');

    var StickUp = {

    };

    module.exports = StickUp;
});

6.jquery库包装

define(function () {

//这里是jquery源码

return $.noConflict();
});