js模块化

commonjs AMD CMD

node 用commonjs

1
var express = require('express')
//同步全部加载模块 在服务器端没事 在前端不ok

AMD requirejs

1
require([‘jquery’, ‘underscore’, ‘backbone’], function ($, _, Backbone){
    // 干活
 })
//异步去加载3个模块 加载完了才执行回调 回调里是整个程序依赖前面模块要做的事
1
//module.js
define([依赖模块],funciton(依赖模块){
	//导出给别的模块引用的方法
})

//main.js
require(['module'],function(module){
	//do something
})

所以 依赖的模块必须要符合AMD的规范 引入了才起作用

1
require.config({
  baseUrl: 'module/js',     //配置path下的统一目的,以便path中不会分别配置
  path: {                              //配置module路径,以便引用时不用写全路径
      module1: 'module1',
      module2: 'module2',
      module3: 'http://www.site.com/module3'     //若引用的是第三方,可以全部全路径
 },
  shim: {     //对不符合AMD规则的模块引用
      'underscore': {
           exports: '_'          //配置其原对外接口
      },
      'backbone': {
           deps: ['underscore', 'jquery'],     //配置其依赖项
           exports: 'Backbone'
     }
 }
 });

define( ['module1', 'module2' ], function( module1, module2 ){
  module1.doSomthing();
  module2.doSomthing();
  function module3(){
      ...
 }
  return {
      module3: module3
 }
 })

CMD seajs

1
//引用jquery
seajs.config({
  // 设置别名,以方便调用
  alias: {
    'jquery': '/js/jquery-1.8b1.js'
  },
  // 配置 shim 信息,这样我们就可以通过 require('jquery') 来获取 jQuery
  shim: {
    'jquery': {
      exports: 'jQuery'
    }
  }
});
//定义模块
define(function(require, exports, module){//默认传入这3个参数
   //调用jquery
   require('jquery');
    //模块内部对外提供接口 每一个外面需要的方法都通过exports导出
    exports.say = function() {
        $("#form1").html("AAAA");
    };
});
//调用
seajs.use('dom', function(dom) {
    dom.say();
});

require调用 var a = require('路径')

1
//模块内又依赖其他模块用require.async
define(function(require, exports, module) {
  // 异步加载一个模块,在加载完成时,执行回调
  require.async('./b', function(b) {
    b.doSomething();
  });
  // 异步加载多个模块,在加载完成时,执行回调
  require.async(['./c', './d'], function(c, d) {
    c.doSomething();
    d.doSomething();
  });
})
//require()是同步的 require.async()是异步的 用来加载可以延迟加载的模块

除了exports导出 还可以用return

1
define({
  foo: 'bar',
  doSomething: function() {}
})
//适合导出jsonp的模块

define(function(require, exports, module) {
  // 一起导出用module.exports 只能在同步中使用 不能用于异步
  module.exports = {
    foo: 'bar',
    doSomething: function() {}
  };
});

//module.exports的错误用法
// x.js
define(function(require, exports, module) {

  // 错误用法
  setTimeout(function() {
    module.exports = { a: "hello" };
  }, 0);

});
在 y.js 里有调用到上面的 x.js:

// y.js
define(function(require, exports, module) {

  var x = require('./x');

  // 无法立刻得到模块 x 的属性 a
  console.log(x.a); // undefined
});

seajs issuesissues

seajs中调用模块有两种方式,seajs.use(ID) 、 require(ID)。

id命名

•完整绝对路径 例如 “http://example.com/test/js/jquery/jquery.js
•以 “.” 开头 例如 “./home/main” “../main”
•以 “/“ 开头 例如 “/js/home/“
•普通命名 例如 “home/main”

base 添加规则

•完整的绝对路径 不会加base
•以 “.” 开头 会相对于当前(被调用的)模块解析地址。 如果不存在被调用的模块(如seajs.use() ), 则会相对于当前页面解析地址。
•以 “/“ 开头 相对于当前页面的根目录 解析地址
•普通命名 直接加上base前缀

1
//在config中设置base
seajs.config({
    base: "home"  // base值为 "http://example.com/test/js/sea/home"
});

seajs.confg({
    base: "./home"  // base值为 "http://example.com/test/home"
});

seajs.conifg({
    base: "/home"   // base值为 "http://example.com/home"
});

// 在index.html中调sea.js
seajs.config({
    base: "./js"        // base为 "http://example.com/test/js"
    alias: {
        "jquery": "jquery/jquery"
    }
});
// 调用 mian 
seajs.use("home/main");     // 解析后的路径为 "http://example.com/test/js/home/main.js"
// 也可以这么写
seajs.use("./js/home/main");    // 解析路径为 "http://example.com/test/js/home/main.js"

//main.js
define(function(require) {
    var $ = require("jquery");      // "http://example.com/test/js/jquery/jquery.js"

    // 调用 tpl
    var tpl = require("./tpl");     // "http://example.com/test/js/home/tpl.js"

    // 也可以
    var tpl = require("home/tpl");  // "http://example.com/test/js/home/tpl.js"
});

AMD 与 CMD

1
//cmd 依赖写在里面 赖加载 用到再加载 能确保顺序正确 性能较差
define(function(require, exports, module) {
  var a = require('./a')
  a.doSomething()
  var b = require('./b')
  b.doSomething()
})
//amd 依赖写在define数组里 预先加载 不能保证顺序 速度快
define(['./a','./b'],function(a,b){
   a.doSomething()
   b.doSomething()
})