SeaJS之use函数

有了 define 等模块定义规范的实现,我们可以开发出很多模块。但光有一堆模块不管用,我们还得让它们能跑起来。在 SeaJS 里,要启动模块系统很简单:

<script src=”path/to/sea.js”></script>
<script>
seajs.use(‘./main’);
</script>

seajs.use 用来在页面中加载模块。通过 use 方法,可以在页面中加载任意模块。
语法:seajs.use seajs.use(id, callback?)

// 加载模块 main,并在加载完成时,执行指定回调
seajs.use(‘./main’, function(main) {
main.init();
});

use 方法还可以一次加载多个模块:

// 并发加载模块 a 和模块 b,并在都加载完成时,执行指定回调
seajs.use([‘./a’, ‘./b’], function(a, b) {
a.init();
b.init();
});

callback 参数可选。当只加载一个模块,且不需要 callback 时,可以用 data-main 属性来简化,:<script src=”path/to/sea.js” data-main=”./main”></script>

上面的代码等价于:

<script src=”path/to/sea.js”></script>
<script>
seajs.use(‘./main’);
</script>

SeaJS 还提供 data-config 来加载配置文件:

<script src=”path/to/sea.js” data-config=”path/to/config”></script>
data-config 等价:
seajs.config({
preload: [‘path/to/config’]
});

路径解析规则与 seajs.use 一致。

我这里用的是:
<script src=”/js/lib/sea.js” data-config=”/js/config.js”></script>
<script>
seajs.use(‘/js/main’, function(main) {
main.banner_focus(‘#focus’);
});

注:main为模块名。main.method为模块定义的函数,可以传递参数过去。

SeaJS之define函数

seajs.config 用来对 SeaJS 进行配置。

CMD 规范中,一个模块就是一个文件。代码的书写格式如下:define(factory);
define 接受 factory 参数,factory 可以是一个函数,也可以是一个对象或字符串。
factory 为对象、字符串时,表示模块的接口就是该对象、字符串。

factory 为函数时,表示是模块的构造方法。
用来定义模块。SeaJS 推崇一个模块一个文件,遵循统一的写法:

define(function(require, exports, module) {
// 模块代码
});

也可以手动指定模块 id 和依赖,require, exports 和 module 三个参数可酌情省略,具体用法如下。

define 也可以接受两个以上参数。字符串 id 表示模块标识,数组 deps 是模块依赖。在开发阶段,推荐不要手写 id 和 deps 参数,因为这两个参数可以在构建阶段通过工具自动生成。

define(id, deps, factory)
define(‘hello’, [‘jquery’], function(require, exports, module) {
// 模块代码
});

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

define(function(require, exports) {

// 获取模块 a 的接口
var a = require(‘./a’);

// 调用模块 a 的方法
a.doSomething();

});

在书写模块代码时,必须遵循这些规则。其实只要把 require 看做是语法关键字 就好啦。require 的参数值 必须 是字符串直接量。不要重命名 require 函数,或在任何作用域中给 require 重新赋值。模块 factory 构造方法的第一个参数 必须 命名为 require 。

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

define(function(require, exports) {

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

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

});

除了给 exports 对象增加成员,还可以使用 return 直接向外提供接口。

define(function(require) {

// 通过 return 直接提供接口
return {
foo: ‘bar’,
doSomething: function() {};
};

});

如果 return 语句是模块中的唯一代码,还可简化为:

define({
foo: ‘bar’,
doSomething: function() {};
});

提示:exports 仅仅是 module.exports 的一个引用。在 factory 内部给 exports 重新赋值时,并不会改变 module.exports 的值。因此给 exports 赋值是无效的,不能用来更改模块接口。

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

module.id 模块的唯一标识。

define(‘id’, [], function(require, exports, module) {

// 模块代码

});

上面代码中,define 的第一个参数就是模块标识。

module.exports 当前模块对外提供的接口。

传给 factory 构造方法的 exports 参数是 module.exports 对象的一个引用。只通过 exports 参数来提供接口,有时无法满足开发者的所有需求。 比如当模块的接口是某个类的实例时,需要通过 module.exports 来实现:

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

});

SeaJS之shim插件

SeaJS 中的模块默认都遵守 CMD 规范,但现实中已存在大量普通 JavaScript 类库,比如 jQuery、Underscore 等。使用 shim 插件,可以将这些普通 JS 文件转换成 CMD 模块,从而能在 SeaJS 中正常使用。

seajs.config({
  plugins: ['shim']
});

一旦激活后,alias 配置项就可以接受 shim Object 配置。

seajs.config({
  // 激活 shim 插件
  plugins: ['shim'],

  // shim 配置项
  alias: {
    // jQuery 的 shim 配置
    'jquery': {
      src: 'lib/jquery-1.9.1.min.js',
      exports: 'jQuery'
    },

    // jquery.easing 插件的 shim 配置
    'jquery.easing': {
      src: 'lib/jquery.easing.1.3.js',
      deps: ['jquery']
    }
  }
});

shim Object

shim Object 是一个对象:

'key': {
    src: String,
    deps: Array,
    exports: String | Function
  }

src 是字符串,表示文件路径。

deps 是数组,指定模块依赖

exports 表示 require(key) 时应该返回哪个全局变量,比如 jquery 的是返回 jQuery 全局变量。exports 也可以是一个函数:

'jquery': {
   src: 'lib/jquery-1.9.1.min.js',
   exports: function() {
   return jQuery.noConflict();
  }
}

通过 shim 插件,可以加载任何非 CMD 模块。

说明:一般在config中使用,先激活plugins: [‘shim’],然后在alias中配置要引用的插件,例如jquery等。