No description, website, or topics provided.
JavaScript Perl
Switch branches/tags
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
bin
demo
doc
lib
src
tool
.gitignore
Makefile
README.md
TODO.txt
package.json

README.md

loader

基于浏览器的 js 代码管理加载器

API

module(modName, [, dependenceList], init(mod)[, modConfig])

描述

模块定义

参数描述

  • modName - 模块名以.分隔,因为需要和路径映射,通常符合文件命名规则即可
  • dependenceList - 依赖模块列表,指定模块名即可,支持指定@,可选
    当模块被加载时,其依赖会作为模块的一部分被加载,
    如果需要异步的加载其他模块,可以使用 require(modList, cb())
    此处默认 ns 跟当前模块所在 ns 相同
  • init - 模块初始化函数,在引用模块(require)的时候被调用,以初始化模块
    此时,模块及模块的全部依赖都加载完毕
  • modConfig - 模块配置 {}
    • autoinit: true/false - 当模块及所有依赖加载完成后,立即初始化,
      而不等待被引用
    • embed: [] - 嵌入资源文件,用法见下面的例子,
      资源文件会在模块初始化之前,跟随模块一起被加载
    • provide: [] - 提供额外的 modName ,接口尚不稳定

用法

1

// file a/b.js
module("a.b", function (mod) {
    mod.init = function () {
        // do some thing
    };

    return {
        foo: function () {
            alert("i'm " + mod._NAME);
        }
    };
});

通常每个模块存放到独立的 js 文件中,像上面一样
模块的初始化函数接收参数 mod ,这就是 require("a.b") 返回的结果啦(通常是这样,有例外)
模块可以对外提供属性和方法,添加的方式有2种:

  • 设置 mod.prop = abc
  • 在 init 函数内返回 { prop: abc } 这样的属性、方法列表

模块内置了以下属性和方法:

  • _NAME - 模块名
  • embed() - 获取模块嵌入资源,这里接受的资源名和模块配置相同
  • _getCfg() - 获取模块内部定义,慎用

2

// file a/c.js
module("a.c", ["a.b"] function (mod) {
    var b = require("a.b");

    return {
        foo: function () {
            alert("embed got " + mod.embed("embed/c.jst"));
            // 这里可以得到 c.jst 的文件内容,配合模版引擎就可以用了
        }
    };
}, {embed: ["embed/c.jst"]);

// file a/embed/c.jst
<% ctx.a %>
"some"
'text'

mod.embed() 可以得到嵌入资源内容 没有参数返回全部资源对象,key 是文件名
如果传入一个文件名,返回对应的文件内容 如果传入多个文件名,返回 资源列表

embed 文件的查找规则是 获取当前模块的加载路径,去掉文件名,拼上资源文件名,获取
资源文件是通过 ajax 获取的,所以,通常用于同域名开发阶段(跨域也可以,需要服务器支持
详情见 tool/embed.ngx 文件)

模块文件可以通过 tool/embed.js 来编译,这样 embed 资源都会被内嵌到模块文件内
(依赖 nodejs 和 uglify-js)

require(modAname, [, modBname], onAllLoad(modA ..))

描述

模块加载

参数描述

  • modAname - 需要加载的模块列表,可指定多个模块,每个模块支持指定独立的 ns
  • onAllLoad - 模块加载完成后的回调函数

返回值

如果待加载的模块全部可用(已加载),这里返回 true 否则返回 false

require 会并行加载全部模块,
模块加载后,会继续加载各模块的依赖,
所有模块及其依赖加载完毕后,会加载所有模块的资源文件(embed)
资源文件加载完毕后,开始调用 onAllLoad,
如果函数有参数,会主动初始化 require 的各个模块,并传递给 onAllLoad
(这里依赖 onAllLoad.length,所以函数内部使用 arguments 也许不是你想要)

用法

1

// file t.html
require("a.c", function (c) {
    c.foo();
    require("a.b", function (b) {
        b.foo();
    }) || alert("loading a.b");
});

require(modAname, [, modBname])

描述

模块引用
没有回调函数的 require 是引用,有回调函数的是加载

参数描述

  • modAname - 需要引用的模块列表,一般只指定1个,支持多个

返回值

返回模块,需要模块已加载,无论是显式加载或者被模块依赖进来
如果给定多个参数,返回 模块数组
如果待引用的模块未正确加载,则抛异常

用法

1

// file t.html
require("a.c", function () {
    require("a.c").foo();

    require("a.b", function () {
        require("a.b").foo();
    }) || alert("loading a.b");
});

require.config([ns, ]config)

描述

配置 ns
ns 一般作用于模块加载和指定模块依赖的时候,因为这些地方需要计算模块对应的加载地址
指定 ns 的方式是在模块名后加 @lib ,其中 @ 是关键字,lib 是 ns 的名字
每个 ns 有自己独立的配置
loader 内部是根据每个 ns 的 path 设置来计算模块名到加载路径映射的

参数描述

  • ns - 指定配置哪个 ns,不指定就配置默认的那个
  • config - 具体的配置 {}
    • path: "" - 形式如 /js/m/?.js
      loader 得到需要加载的模块后,会解析模块名和 ns ,
      得到对应 ns 下面的 path
      同时对模块名做替换,把 . 替换为 / ,然后替换 path 内的 ? 符号
      就得到了最终的加载路径
    • pkg: { "pkgname": ["modA", "modB"] } -
      计算模块加载路径的时候,会预先判断是否有某个 pkg 提供了此模块,
      如果有,就直接使用 pkg 代替当前模块去计算加载路径了 :)

用法

1

// file http://a.ux/lib/jquery.js
module("jquery", function () {
    // jquery
});

// file http://a.ux/lib/jquery/tmpl.js
module("jquery.tmpl", ["jquery"], function () {
    // jquery.tmpl
});

// js/main.js
module("main", ["jquery.tmpl@lib"], function (mod) {
    var tmpl = require("jquery.tmpl").tmpl,
        $ = require("jquery").jquery;

    mod.init = function (sel) {
        $(sel).html(tmpl(mod.embed("main.jst"), {}));
    };
}, {embed: ["main.jst"]});

// app.html
require.config("lib", { path: "http://a.ux/?.js" });
require.config({ path: "js/?.js" });

require("main", "jquery@lib", function (main, $) {
    main.init($(document.body));
});

require.at(ns)

描述

当需要从某个 ns 加载大量模块的时候,可以使用此函数,
免去给每个模块都添加 @ns 的麻烦

require("a@lib", "b@lib", cb) 等价于
require.at("lib")("a", "b", cb)

module._genDepsDot()

描述

获取当前页面所有已加载模块的依赖图(dot 格式)
不复杂的 dot 可以在线解析( http://ashitani.jp/gv/ )
或者自己安装 http://www.graphviz.org/ 使用

TODO

  • 版本 + 时间戳问题 - 细化到 @ns , module ?
  • 插件式模块,一般不提供直接的接口,都是挂接接口到其他接口上,这类接口一旦引入,应该自动初始化 autoinit 选项现在的行为有些问题