码迷,mamicode.com
首页 > Web开发 > 详细

Sea.js加载原理

时间:2015-10-10 09:09:54      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:

CMD规范

要想了解Sea.js的运作机制,就不得不先了解其CMD规范。

Sea.js采用了和Node相似的CMD规范,我觉得它们应该是一样的。使用require、exports和module来组织模块。但Sea.js比起Node的不同点在于,前者的运行环境是在浏览器中,这就导致A依赖的B模块不能同步地读取过来,所以Sea.js比起Node,除了运行之外,还提供了两个额外的东西:

  1. 模块的管理
  2. 模块从服务端的同步

即Sea.js必须分为模块加载期和执行期。加载期需要将执行期所有用到的模块从服务端同步过来,在再执行期按照代码的逻辑顺序解析执行模块。本身执行期与node的运行期没什么区别。

所以Sea.js需要三个接口:

  1. define用来wrapper模块,指明依赖,同步依赖;
  2. use用来启动加载期;
  3. require关键字,实际上是执行期的桥梁。

并不太喜欢Sea.js的use API,因为其回调函数并没有使用与Define一样的参数列表。

模块标识(id)

模块id的标准参考Module Identifiers,简单说来就是作为一个模块的唯一标识。

出于学习的目的,我将它们翻译引用在这里:

  1. 模块标识由数个被斜杠(/)隔开的词项组成;
  2. 每次词项必须是小写的标识、“.”或“..”;
  3. 模块标识并不是必须有像“.js”这样的文件扩展名;
  4. 模块标识不是相对的,就是顶级的。相对的模块标识开头要么是“.”,要么是“..”;
  5. 顶级标识根据模块系统的基础路径来解析;
  6. 相对的模块标识被解释为相对于某模块的标识,“require”语句是写在这个模块中,并在这个模块中调用的。

模块(factory)

顾名思义,factory就是工厂,一个可以产生模块的工厂。node中的工厂就是新的运行时,而在Sea.js中(Tea.js中也同样),factory就是一个函数。这个函数接受三个参数。

function (require, exports, module) {
    // here is module body
}

在整个运行时中只有模块,即只有factory。

依赖(dependencies)

依赖就是一个id的数组,即模块所依赖模块的标识。

 

node的方式-同步的require

想要解释这个问题,我们还是从Node模块说起,node于Ruby类似,用我们之前使用过的一个模块作为例子:

// File: usegreet.js
var greet = require("./greet");
greet.helloJavaScript();

当我们使用node usegreet.js来运行这个模块时,实际上node会构建一个运行的上下文,在这个上下文中运行这个模块。运行到require(‘./greet‘)这句话时,会通过注入的API,在新的上下文中解析greet.js这个模块,然后通过注入的exportsmodule这两个关键字获取该模块的接口,将接口暴露出来给usegreet.js使用,即通过greet这个对象来引用这些接口。例如,helloJavaScript这个函数。详细细节可以参看node源码中的module.js

node的模块方案的特点如下:

  1. 使用require、exports和module作为模块化组织的关键字;
  2. 每个模块只加载一次,作为单例存在于内存中,每次require时使用的是它的接口;
  3. require是同步的,通俗地讲,就是node运行A模块,发现需要B模块,会停止运行A模块,把B模块加载好,获取的B的接口,才继续运行A模块。如果B模块已经加载到内存中了,当然require B可以直接使用B的接口,否则会通过fs模块化同步地将B文件内存,开启新的上下文解析B模块,获取B的API。

实际上node如果通过fs异步的读取文件的话,require也可以是异步的,所以曾经node中有require.async这个API。

 

Sea.js加载原理

标签:

原文地址:http://www.cnblogs.com/8minutes/p/4865678.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!