SeaJS 1.2.1 模块开发须知

SeaJS 模块开发须知(seajs1.2.1)

1.SeaJS的全局接口

加载seajs后,SeaJS向全局公开了两个标识符: seajs 和 define。 
如果你的项目中已经用了标识符seajs,又不想改。这时SeaJS可以让出全局的seajs。如

var myseajs = seajs.noConflict();

这时myseajs就相当于先前的seajs。 
用过jQuery的同学应该很熟悉$.noConflict方法,SeaJS的noConflict与之类似。

2.SeaJS的模块定义

SeaJS默认使用全局的define函数写模块(可把define当成语法关键字)。 
有了define函数,模块所在的js文件被加载后不会马上执行模块的代码,只是执行define函数。 
模块加载器有机会在模块执行前做预处理。

define定义了三个形参id, deps, factory。

define(id?, deps?, factory);

?表示id和deps可选。

id为字符串,遵循 [Module Identifiers](http://wiki.commonjs.org/wiki/Modules/1.0#Module_Identifiers)。
SeaJS 中的模块标识是 CommonJS 模块标识 的超集:  

英文
1.A module identifier is a String of "terms" delimited by forward slashes.   
2.A term must be a camelCase identifier, ".", or "..".   
3.Module identifiers may not have file-name extensions like ".js".   
4.Module identifiers may be "relative" or "top-level". A module identifier is "relative" if the first term is "." or "..".   
5.Top-level identifiers are resolved off the conceptual module name space root.   
6.Relative identifiers are resolved relative to the identifier of the module in which "require" is written and called.   

中文  
1.一个模块标识由斜线(/)分隔的多项组成。  
2.每一项必须是小驼峰字符串,”.“或 ”..“。  
3.模块标识可以不包含文件后缀名,比如 ”.js“ 。  
4.模块标识可以是 相对 或 顶级 标识。如果第一项是”.“或”..“,则该模块标识是相对标识。  
5.顶级标识根据模块系统的基础路径来解析。
6.相对标识相对 require 所在模块的路径来解析。

注意,符合上述规范的标识肯定是 SeaJS 的模块标识,但 SeaJS 能识别的模块标识不需要完全符合以上规范。 
比如,除了大小写字母组成的小驼峰字符串,SeaJS 的模块标识字符串还可以包含下划线(_)和连字符(-), 
甚至可以是 http://、https://、file:/// 等协议开头的绝对路径。

deps 指依赖模块,类型为数组。

factory 可以是一个函数,也可以是对象、字符串等类型。

factory 为对象、字符串等非函数类型时,表示模块的接口就是该对象、字符串等值。比如可以如下定义一个 JSON 模块:

define({ 
    "name": "whoami",
    "email": whoami@gmail.com
});

可以通过字符串定义模板模块:

define('My name is {{name}} . My Email is {{email}}.');

factory 为函数时,表示模块的构造方法,执行该方法,可以得到模块向外提供的接口。 
factory 默认会传入三个参数:require、exports 和 module。 
require参数用于获取外部的模块的接口,类似java 或者python中的import语句。 
exports参数用于申明模块对外提供的接口和属性。如果函数有返回值,以return的结果作为exports值。 
module 参数提供模块自身的信息。可以通过module.exports来暴露对外的接口和属性,exports 是module.exports的一个引用。

有如下的一个main.js,包括如下的代码。

define(function(require, exports, module) {

  // The module code goes here
  //模块加载的时候会执行该匿名函数的代码,并返回exports对象。  
  //如果只是想让模块执行的运行包含在匿名函数内部的代码,可以不用exports。  

  require('./util');          //自定义模块,可以用相对js文件的路径引用
  require('jquery');          //系统预置模块,可以通过预定义的别名引用

  console.log('hello seajs');  
  ...

  function foo(){

    ...
  }

  exports.foo = foo; 

});

注意:如果没有指定id,deps参数, factory匿名函数的requre、exports和module的3个参数的名字不能修改。

backbone.js模块化的定义例子:

define('gallery/backbone/0.9.2/backbone', ['underscore', 'jquery'], function(require, exports){

    ...
})   

通过工具部署后,会自动提取id和deps信息,一般的业务开发可以不用填写id和deps参数。

2.SeaJS的模块和文件的关系

业务开发一般一个模块对应一个javascript文件  
通过工具(SPM)来部署模块,可以自动提取id和deps信息,可以把多个模块合并成一个文件。  
如果调试的时候想知道模块路径会解析成什么样子,可以打印require.resolve的结果。  

3.SeaJS文件后缀的自动添加规则

除非在路径中有问号(?)或最后一个字符是井号(#),SeaJS 在解析模块标识时, 
都会自动添加 JS 扩展名(.js)。如果不想自动添加扩展名,最简单的方法是, 在路径末尾加上井号(#)。

// ".js" 后缀可以省略:
require.resolve('http://example.com/js/a');
require.resolve('http://example.com/js/a.js');
  // => http://example.com/js/a.js

// ".css" 后缀不可省略:
require.resolve('http://example.com/css/a.css');
  // => http://example.com/css/a.css

// 当路径中有问号("?")时,不会自动添加后缀:
require.resolve('http://example.com/js/a.json?callback=define');
  // => http://example.com/js/a.json?callback=define

// 当路径以井号("#")结尾时,不会自动添加后缀,且在解析时,会自动去掉井号:
require.resolve('http://example.com/js/a.json#');
  // => http://example.com/js/a.json

4.SeaJS的模块加载和执行

在模块的外部,可以通过seajs.use(ids, callback)方法可用来异步加载并执行模块。 
use方法可用来异步加载模块,并在加载完成后执行指定回调。

//异步执行主模块
seajs.use('./main');

//异步执行多个模块
seajs.use(['./main1', './main2']);

//异步执行,并调用模块提供的接口
seajs.use('jquery',function($){
    //do something
}

//支持多个模块执行
seajs.use('./a','./b',function(a,b){
   //do something
}

在模块的内部,还可以通过匿名函数提供的require参数,调用require.async(ids, callback)来执行模块。 
async方法可用来异步加载模块,并在加载完成后执行指定回调。

define(function(require, exports, module) {

  //异步执行主模块
  require.async('./a');

  //异步执行多个模块
  require.async(['./a', './b'];


   //异步执行,并调用模块提供的接口
  require.async('./b', function(b) {
    b.doSomething();
  });

  //加载并执行多个模块,调用相关的模块接口
  require.async(['./c', './d'], function(c, d) {
    // do something
  });
});

seajs.use和require.async内部其实都是调用Module._use(ids, callback)来执行模块的代码.

 

  以上的文字都是基于markdown编写后拷贝浏览器执行的结果到这里,好像排版还可以。:-)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值