seajs配置问题详解以及seajs一些插件的使用

base配置:

  seajs.config({
	 base:"http://localhost:8080/sealJs/"}
note:  这里是设置基础的文件夹,所有路径都是相对于他来说的
alias配置: (alias就是当模块标识很长的时候用的方式)

alias: 
{ 
 'jquery1': 'moduler1/fakeJquery',/*相对地址,相对于base来说的,表示http://localhost:8080/sealJs/moduler1/fakeJquery.js可以用require('jquery1')完成*/
 'diralias':"http://localhost:8080/sealJs/moduler1/directalias.js"/*如果是直接地址表示的别名,那么不是相对于base来说的,而是绝对路径*/
} 
note:如果是相对地址就是相对于base路径来说的。
paths配置:

    paths:
	 {
	 'm1':'moduler1',
	 /*paths表示当要分文件夹管理,或者文件的目录很深的时候用的方式,路径也是相对于base来说的
	  所以:m1表示http://localhost:8080/sealJs/moduler1/,a.js就是m1/a
	      m3表示http://localhost:8080/sealJs/moduler3/,a.js就是m3/a
	 */
	 'm3':'moduler3',
	 'lug':"language"
	 }
note: 当路径嵌套很深的时候我们用paths来配置,或者要分文件夹管理的时候可以用这种方式,也是相对于base来说的。
vars配置:

     vars: /*如果模块路径在运行时候才能确定,那么我们就用vars来配置*/
	 {
	   'locale':"zh-cn"
	 }
note:这当我们要改成英文文件的时候就只要在这里修改就可以了,特别有利于动态的加载过程。调用方式如下:

    //下面我们调用通过vars来指定的动态路径下面的文件,这种方式可以有利于多个模块之间的动态切换
	    var lg=require("lug/{locale}.js");
	    lg.sayLanguage();
charset配置:

 /*指定加载link或者script标签时候的编码方式*,可以是字符串也可以是一个函数*/
	 charset:function(url)
	 {
	   if(url.indexOf("http://localhost:8080/sealJs/xxx")===0)
	   {
	     return 'gbk';/*xxx目录下的文件用gbk编码*/
	   }
	   return "utf-8"; /*其它用UTF-8*/
	 }
map配置:

/*map用于对模块路径进行映射修改,可用于路径转换,在线调试等
	    map:[
	           [".js","-debug.js"]
	         ]
	 这种映射方式将会使得所有的.js变成后缀为-debug.js的文件,下面这种映射将会使得对zh-cn.js的访问变成对zh-cn1.js的访问
	  map:[
	  ["http://localhost:8080/sealJs/language/zh-cn.js","http://localhost:8080/sealJs/language/zh-cn1.js"]
	 ]
	 */
debug配置:

debug:true/*值为true时候,加载器不会删除动态插入的script标签,插件可以通过debug来决定log的输出信息*/
use方法:

/*调用具体的模块,调用格式为seajs.use(id, callback?),其中回调可以省略,也可以同时加载多个模块(第一个参数是数组),这时候回调函数的参数的顺序就是前面加载的
   模块的顺序,类似于Deferred对象的参数顺序!调用方式为: seajs.use("moduler2/moduler2.js");
   seajs.use和domReady没有任何关系,如果要保证domready后才执行特定的逻辑,用jquery来保证。不过要加载jquery首先要jquery自己完成模块化
   我用的jquery-1.11.3修改其中的代码if ( typeof define === "function" && define.amd )为if ( typeof define === "function")就可以了!
 我这时候把jquery放在工程根目录下面:
 */
  seajs.use(["jquery","moduler2/moduler2"],function($,main)
  {
    $(document).ready(function()
    {
       //如果要在domReady事件后执行相应的逻辑,我们就放在这个方法里面!
       //注意:use方法第一个参数一定要有,但是可以是null或者一个变量!
       main.init();
    });
    
注意:我用的是 jquery.1-11.3,所以要把下面的代码进行修改:

if ( typeof define === "function" && define.amd ) {
	define( "jquery", [], function() {
		return jQuery;
	});
}
修改为:

if ( typeof define === "function" ) {
	define( "jquery", [], function() {
		return jQuery;
	});
}
note:很显然,这时候的就query就自己进行了模块化了,其中id就是jquery字符串。 这时候我把jquery.js放在了根目录了,当然也可以自己配置。
cache配置:

如果要知道模块信息可以通过在chorome浏览器中console中输入:seajs.cache就可以看到!可以查阅当前模块系统中所有模块的信息,他遵守CMD规范,满足一个文件就是一个模块。

resolve配置:

 //用seajs.resolve对传入的字符串进行路径解析
    var result=seajs.resolve('jquery1');
    console.log(result);
note:这时候可以通过resolve把传入的字符串解析为 路径信息。如会把上面的jquery1解析为:http://localhost:8080/sealJs/moduler1/fakeJquery.js也就是表示具体的路径。

define函数:

调用方式为:define define(id?, deps?, factory)
   字符串 id 表示模块标识,数组 deps 是模块依赖。id 和 deps 参数可以省略。省略时,可以通过构建工具自动生成。注意:带 id 和 deps 参数的 define 用法不属于 CMD 规范,而属于 Modules/Transport 规范。
define.cmd:

一个空对象,可用来判定当前页面是否有 CMD 模块加载器:

if (typeof define === "function" && define.cmd) {//从上面的jquery源码中jquery判断了define.amd,而不是define.cmd!
  // 有 Sea.js 等 CMD 模块加载器存在
}
factory具有的三个参数:

参数1:require参数

  该参数是模块标识符,如上面通过paths配置或者alias配置的键名都是模块标识符,如果define的时候没有模块标识符,那么就是该文件的地址。

参数2:exports对象

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

define(function(require, exports) {
  // 对外提供 foo 属性
  exports.foo = 'bar';
  // 对外提供 doSomething 方法
  exports.doSomething = function() {};
});
提示exports 仅仅是 module.exports 的一个引用。在 factory 内部给 exports 重新赋值时,并不会改变 module.exports 的值。因此给 exports 赋值是无效的,不能用来更改模块接口。exports表示向外提供的接口,是一个object对象,只有在exports中的方法外部能访问,内部的变量都是私有的变量,外部无法访问。提供外部接口的方法有三种,第一种就是直接绑定在exports对象上面;第二种就是直接返回一个对象;第三种方法,如果return是内部唯一的代码,那么可以直接define({json对象})!如下:

define(function(require, exports, module) {
  // 直接绑定到module的exports对象上面!
  module.exports = {
    foo: 'bar',
    doSomething: function() {}
  };
});

如果我们需要返回的暴露的对象是一个特定的类型,那么我们就可以通过重置exports对象

seajs配置为:

   seajs.config({
		 base:"http://localhost:8080/sealJs/"
	 });
	 seajs.use("add2allmoduler/extend");
	 seajs.use("add2allmoduler/a");
extend.js模块为:

define(function(require, exports, module) {
	function someClass(){
		this.name="qinliang";
		this.sex="male";
	}
	//exports已经是被重置了,也就是这时候的exports就是someClass类型的对象
	//同时可以通过 module.exports为这个新的exports对象添加新的属性和方法
	  module.exports = new someClass();
	  module.exports.sayName=function()
	  {
		  return "qinliang sayName";
	  }
});
a.js模块(用于调用extend模块的代码)

define(function(require, exports, module) {
var exports=require("add2allmoduler/extend");
//获取到extend模块暴露出来的公有的属性!
console.log(exports.name);
//获取到extend模块暴露出来的共有方法
  console.log(exports.sayName());
});

参数3:module

具有id,url,dependencies,exports属性(Array类型)打开图表查看(从该图中可以看出dependencies是5,因为moduler2.js是整个工程的main函数),其中id就是define函数的第一个参数,url根据模块系统的路径解析规则得到的模块绝对路径。dependencies 是一个数组,表示当前模块的依赖。一般情况下(没有在 define 中手写 id 参数时),module.id 的值就是 module.uri,两者完全相同。传给 factory 构造方法的 exports 参数是 module.exports 对象的一个引用。只通过 exports 参数来提供接口,有时无法满足开发者的所有需求。 比如当模块的接口是某个类的实例时,需要通过 module.exports来实现,j见上例:

define(function(require, exports, module) {
  // exports 是 module.exports 的一个引用
  console.log(module.exports === exports); // true
  // 重新给 module.exports 赋值
  module.exports = new SomeClass();
  // exports 不再等于 module.exports
  console.log(module.exports === exports); // false
});
注意:对module.exports赋值需要同步执行,不能放在 回调函数里面

module.constructor

当我们需要为所有的模块都添加一个共同的方法的时候,我们就可以用moduler的constructor属性:

在主页中我们调用了extend.js和a.js代码如下:

  seajs.config({
		 base:"http://localhost:8080/sealJs/"
	 });
	 seajs.use("add2allmoduler/extend");
	 seajs.use("add2allmoduler/a");
extend.js中代码如下:

define(function(require, exports, module) {
	//当需要添加一个方法或者属性到所有的模块中,我们就需要用到module.constructor属性!
  var Module = module.constructor;
  //打印为module的构造函数function t(a,b){this.uri=a,this.dependencies=b||[],this.deps={},this.status=0,this._entry=[]}
  //console.log(Module);
  Module.prototype.filename = function() {
    var id = this.id;
    //调用filename是a.js,所以这里的id为:http://localhost:8080/sealJs/add2allmoduler/a.js
   // console.log("id="+id);
    var parts = id.split('/');
   //返回文件名
    return parts[parts.length - 1];
  };
});
note:在extend中我们通过获取到 module的constructor属性,然后为其prototype中添加一个共同的函数,那么在其它页面中如a.js中就可以通过module访问这个共有的方法:

define(function(require, exports, module) {
	//filename方法就是通过前面的moduler的constructor属性添加的方法,也会封装到该define方法具有的module参数上。调用filename的this就是这个module!
	//console.log(module.filename);
  exports.filename = module.filename();
});

require.constructor

有时候,我们需要给所有 require 参数对象添加一些公用属性或方法。这时, 使用 require.constructor 来实现会非常方便。

和module的上面的例子一样,我们通过require的constructor为require添加共有属性和方法:

 seajs.config({
		 base:"http://localhost:8080/sealJs/"
	 });
	 seajs.use("add2allmoduler/extend");
	 seajs.use("add2allmoduler/a");
extend.js代码:

define(function(require, exports, module) {
	//打印:Function() { [native code] }
	//console.log(require.constructor);
    var requireC=require.constructor;
    //为所有的require对象添加一个方法filename方法
    requireC.prototype.filename=function()
    {
    	return "filename";
    }
    requireC.prototype.name="qinlaing";
});
a.js源码:

define(function(require, exports, module) {
 var filename=require.filename();
 //调用函数
 console.log(filename);
 //绑定到require上面的属性,通过constructor绑定的!
 console.log(require.name);

});
note:我们看到,上面的 filename,name都通过了require的constructor属性, 结合prototype 实现了属性和方法的共享

require.async函数:调用格式require.async(id,callback?)

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();
  });
});
注意: require 是同步往下执行, require.async 则是异步回调执行。 require.async  一般用来加载可延迟异步加载的模块。

seajs.data属性:

通过 seajs.data,可以查看 seajs 所有配置以及一些内部变量的值,可用于插件开发。当加载遇到问题时,也可用于调试。控制台输入seajs.data可以获取到所有的配置信息。

seajs.log方法:

log方法默认不会显示,当seajs.debug为true时候才会显示。该方法用于log插件的开发。这时候需要在页面引入seajs.log.js!

preload配置项:

用于在普通模块加载前加载指定的模块。其中空字符串会被忽略。注意:preload中的配置,需要等到 use 时才加载。但是会保证在use中的模块加载之前,preload中的模块已经加载完成。

// 在老浏览器中,提前加载好 ES5 和 json 模块
seajs.config({
    preload: [
        Function.prototype.bind ? '' : 'es5-safe',
        this.JSON ? '' : 'json'
    ]
});
注意:preload配置不能放在模块文件里面。
seajs.config({
    preload: 'a'
});
define(function(require, exports) {
    // 此处执行时,不能保证模块 a 已经加载并执行好
});
下面我们学习一下几个常见的插件:

(1)seajs-style插件(加载一段css代码)

通过下面的步骤完成:
 <script src="seajs-style.js"></script>//引入插件
 seajs.importStyle("body { background-color: red; }")//执行importStyle方法就会通过构建一个style标签插入到页面中。第二个参数是id,用于指定style的id属性。
note:这种方式插入时候需要对\0等转义为\\0;在IE下style不能超过31个,否则seajs会抛出异常。详见 importStyle官方文档
 (2)seajs.css插件 (用于加载一个css文件)

通过下面的步骤来完成使用

    <script src="seajs-css.js"></script>
    seajs.use("css/style.css")
note:这个插件和link标签一样,用于加载一个css文件。
(3)preload插件的使用
 <script src="seajs-preload.js"></script>
      seajs.config({
    preload: ['jquery']
   })
seajs.use("path/to/mod");//preload中的模块会等到use调用的时候才会加载,但是会在path/to/mod模块加载之前完成,基于seajs2.3.0!
(4) flush和combo插件的使用
<script src="path/to/sea.js"></script>
<script src="path/to/seajs-combo.js"></script>
<script src="path/to/seajs-flush.js"></script>
<script>
seajs.use(['a', 'b'], function(a, b) {
  // ...
})
seajs.use(['c', 'd'], function(c, d) {
  // ...
})
// The combined request is http://test.com/path/to/??a.js,b.js,c.js,d.js
seajs.flush()
</script>
note:这种方式可以将所有的http请求一次性发送出去。
(5)seajs. log插件
<script src="path/to/sea.js"></script>
<script src="path/to/seajs-log.js"></script>
<script>
  seajs.log('hello world','warn')//警告信息
</script>
注意console.log 信息默认不会显示,在 Sea.js 的 debug 为 true 时才显示。
(6)seajs.text插件使用
<script src="path/to/sea.js"></script>
<script src="path/to/seajs-text.js"></script>
<script>
define("main", function(require) {
  // You can require `.tpl` file directly
  var tpl = require("./data.tpl")
})
</script>
note:该插件用于加载json,tpl,html后缀等文件
  1. Sea.js 通过 XHR 来加载文本文件。受同源策略限制,在开发完成后,推荐通过构建工具将文本文件转换为 JS 代码。这样,上线后就可以从任意域加载

  2. Sea.js 原生支持 css 文件的加载,直接 require('path/to/file.css') 即可

(7)health插件的使用

<script src="path/to/sea.js"></script>
<script src="path/to/seajs-health.js"></script>
<script>
// You can use seajs.health method to collecting health data.
var healthData = seajs.health()
</script>
note: health插件用于检测CMD的模块的健康状况。
(8)debug插件的使用
seajs.config({
  "alias": {
    "seajs-debug": "path/to/seajs-debug"
  }
})
然后在URL中加入?seajs-debug,并且重新加载页面

总结:

如果说jQuery找不到,那么就要按照上面修改jQuery源码相关部分;同时这种动态加载的方式会在缓存中,即使用Ctr+F5刷新也会读取缓存,除非手动清除缓存;掌握module.constructor.prototype和require.constructor.prototype,module.exports实现数据共享!

有时候为了保证DOM加载完成从而进行业务逻辑的处理,可以用jQuery保证DOM加载完全:

seajs.use(["jquery"],function($)
  {
    $(document).ready(function()
    {
      $('input').click(function()
      {
        seajs.use(['hello'],function(hello)
        {
           hello.sayHello();
        });
      })
      
    });

你可能感兴趣的:(seajs配置问题详解以及seajs一些插件的使用)