SeaJs 初学

来源:互联网 发布:怎样更换淘宝账号 编辑:程序博客网 时间:2024/04/28 15:46

SeaJs为解决问题

SeaJS是一个遵循CommonJS规范的JavaScript模块加载框架,可以实现JavaScript的模块化开发及加载机制。与jQuery等JavaScript框架不同,SeaJS不会扩展封装语言特性,而只是实现JavaScript的模块化及按模块加载。SeaJS的主要目的是令JavaScript开发模块化并可以轻松愉悦进行加载,将前端工程师从繁重的JavaScript文件及对象依赖处理中解放出来,可以专注于代码本身的逻辑。SeaJS可以与jQuery这类框架完美集成。使用SeaJS可以提高JavaScript代码的可读性和清晰度,解决目前JavaScript编程中普遍存在的依赖关系混乱和代码纠缠等问题,方便代码的编写和维护。

seaJs与传统Js模块化编程对比

例如有4个模块:module1.js, module2.js, module3.js, module4.js

  • 传统方式:
    需要在index.html中加载全部4个js

  • seaJs
    只需要加载sea.js,由sea.js去解析各个模块需要哪些js。但是各个模块需要按照define的格式编写。
    js代码以模块进行组织,各个模块通过require引入自己依赖的模块,代码清晰明了

seaJs开发基本原则

一切皆为模块

有点类似于面向对象中的类——模块可以拥有数据和方法,数据和方法可以定义为公共或私有,公共数据和方法可以供别的模块调用。

每个模块应该都定义在一个单独js文件中,即一个对应一个模块。

模块定义与编写

  • 使用define定义模块
fn.define = function(id, deps, factory) {    //code of function…}

define可以接收的参数分别是模块ID,依赖模块数组及工厂函数。
define对于不同参数个数的解析规则如下:
如果只有一个参数,则赋值给factory。
如果有两个参数,第二个赋值给factory;第一个如果是array则赋值给deps,否则赋值给id。
如果有三个参数,则分别赋值给id,deps和factory。
几乎所有用到define的地方都只传递一个工厂函数进去,如下:

define(function(require, exports, module) {    //code of the module...});

用一个参数的define定义模块。那么id和deps会怎么处理呢?
id是一个模块的标识字符串,define只有一个参数时,id会被默认赋值为此js文件的绝对路径。如example.com下的a.js文件中使用define定义模块,则这个模块的ID会赋值为
http://example.com/a.js
,没有特别的必要建议不要传入id。deps一般也不需要传入,需要用到的模块用require加载即可。

  • 工场函数factory参数
    工厂函数是模块的主体和重点。在只传递一个参数给define时,这个参数就是工厂函数。
    三个参数分别是:
    1.require——模块加载函数,用于记载依赖模块。
    2.exports——接口点,将数据或方法定义在其上则将其暴露给外部调用。
    3.module——模块的元数据。
    这三个参数可以根据需要选择是否需要显示指定。
    module是一个对象,存储了模块的元信息,具体如下:
    1.module.id——模块的ID。
    2.module.dependencies——一个数组,存储了此模块依赖的所有模块的ID列表。
    3.module.exports——与exports指向同一个对象。
  • 基于export编写模块
define(function(require, exports, module) {    var a = require('a'); //引入a模块    var b = require('b'); //引入b模块    var data1 = 1; //私有数据    var func1 = function() { //私有方法        return a.run(data1);    }    exports.data2 = 2; //公共数据    exports.func2 = function() { //公共方法        return 'hello';    }});
  • 返回对象编写
define(function(require) {    var a = require('a'); //引入a模块    var b = require('b'); //引入b模块    var data1 = 1; //私有数据    var func1 = function() { //私有方法        return a.run(data1);    }    return {        data2: 2,        func2: function() {            return 'hello';        }    };});define({    data: 1,    func: function() {        return 'hello';    }});

模块载入和引用

使用require、seaJs.use、require.async三种方法载入模块
- 绝对路径载入

require("http://example/js/a");

载入http://example/js/a.js

  • 相对路径载入
require("./a");

若当前路径是http://example/js/b.js,那么载入了http://example/js/a.js

  • 基址地址载入
    如果载入字符串标识既不是绝对路径也不是以”./”开头,则相对SeaJS全局配置中的“base”来寻址。
require("jquery");

seajs.use

seajs.use主要用于载入入口模块。入口模块相当于C程序的main函数,同时也是整个模块依赖树的根。上面在TinyApp小例子中,init就是入口模块。seajs.use用法如下:

//单一模式seajs.use('./a');//回调模式seajs.use('./a', function(a) {  a.run();});//多模块模式seajs.use(['./a', './b'], function(a, b) {  a.run();  b.run();});

require

一般都用require加载模块

这里简要介绍一下SeaJS的自动加载机制。上文说过,使用SeaJS后html只要包含sea.js即可,那么其它js文件是如何加载进来的呢?SeaJS会首先下载入口模块,然后顺着入口模块使用正则表达式匹配代码中所有的require,再根据require中的文件路径标识下载相应的js文件,对下载来的js文件再迭代进行类似操作。整个过程类似图的遍历操作(因为可能存在交叉循环依赖所以整个依赖数据结构是一个图而不是树)。

require.async

上文说过SeaJS会在html页面打开时通过静态分析一次性记载所有需要的js文件,如果想要某个js文件在用到时才下载,可以使用require.async

require.async('/path/to/module/file', function(m) {    //code of callback...});

seaJs全局配置

  • seajs.config
seajs.config({    base: 'path/to/jslib/',    alias: {      'app': 'path/to/app/'    },    charset: 'utf-8',    timeout: 20000,    debug: false});

base表示寻址的基址,如果base=“http://example.com/js/3-party/”,则

var $ = require('jquery');

会载入”http://example.com/js/3-party/jquery.js”。

alias可以对较长的常用路径设置缩写。
charset表示下载js时script标签的charset属性。
timeout表示下载文件的最大时长,以毫秒为单位。
debug表示是否工作在调试模式下。

SeaJS如何与现有JS库配合使用

  • 要将现有JS库如jQuery与SeaJS一起使用,只需根据SeaJS的的模块定义规则对现有库进行一个封装。例如,下面是对jQuery的封装方法:
define(function() {//{{{jQuery原有代码开始/*! * jQuery JavaScript Library v1.6.1 * http://jquery.com/ * * Copyright 2011, John Resig * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license * * Includes Sizzle.js * http://sizzlejs.com/ * Copyright 2011, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * * Date: Thu May 12 15:04:36 2011 -0400 *///...//}}}jQuery原有代码结束return $.noConflict();});

参考链接

使用SeaJS实现模块化JavaScript开发
SeaJS入门教程系列之使用SeaJS

0 0
原创粉丝点击