Seajs源码解析系列(二)


前言:上一篇对Seajs及其使用做了简单的介绍,这一章开始正式接触Seajs的源码。
Sea.js 的所有代码都通过 GitHub 管理,项目地址:https://github.com/seajs/seajs
其源码放在src目录下。
目录结构:

scr目录结构:
-------------------------
intro.js             -- 全局闭包头部
sea.js               -- 基本命名空间

util-lang.js         -- 语言增强
util-events.js       -- 简易事件机制
util-path.js         -- 路径处理
util-request.js      -- HTTP 请求
util-deps.js         -- 依赖提取

module.js            -- 核心代码
config.js            -- 配置
outro.js             -- 全局闭包尾部

本章主要对module.js模块进行介绍。
代码分析:
module.js作为整个Seajs的核心,无疑是十分重要的。Seajs作为一个模块加载器,其所有的模块都会作为一个Module对象存储在seajs.cache中。通过seajs.cache,我们可以查阅当前模块系统中的所有模块信息。
一个模块在加载过程中必然会经历以下几个阶段:

var STATUS = Module.STATUS = {
  // 1 - The `module.uri` is being fetched
  FETCHING: 1, //开始加载当前模块
  // 2 - The meta data has been saved to cachedMods
  SAVED: 2, //当前模块加载完成并保存模块数据
  // 3 - The `module.dependencies` are being loaded
  LOADING: 3, //开始加载依赖的模块
  // 4 - The module are ready to execute
  LOADED: 4, //依赖模块已经加载完成
  // 5 - The module is being executed
  EXECUTING: 5, //当前模块执行中
  // 6 - The `module.exports` is available
  EXECUTED: 6, //当前模块执行完毕
  // 7 - 404
  ERROR: 7 //出错
}

同时,我们在内存中使用Module对象来维护模块的信息:

function Module(uri, deps) {
   
  this.uri = uri
  this.dependencies = deps || []//依赖模块ID列表
  this.deps = {} // Ref the dependence modules
  this.status = 0

  this._entry = []//在模块加载完成之后需要调用callback的模块
}

对应模块加载的几个阶段状态,总结模块加载的大致过程如下:

模块方法 方法说明 状态变化
seajs.use 在页面上启动模块系统,加载一个或多个模块
Module.use: 开始加载整个流程 状态变化:FETCHING到SAVED
Module.prototype.load 开始加载子模块 状态变化:SAVED到LOADING
Module.prototype.onload 子模块加载完成时调用 状态变化:LOADING到LOADED
Module.prototype.exec 加载过程结束,开始执行模块 状态变化:EXECUTING到EXECUTED

接下来,我们来具体的看一下Seajs模块加载的具体过程:


1.首先,我们来看一下seajs.use,这是整个模块加载的启动器。

/**
 * 用来在页面中加载一个或多个模块
 * @param ids 模块名 (文件路径)
 * @param callback 回调函数
 */
seajs.use = function(ids, callback) {
   
  Module.use(ids, callback, data.cwd + "_use_" + cid())
  return seajs
}

示例如下:

seajs.use("./main",function(main){
   
    main.init();
})

我们可以传入想要加载的模块名以及回调函数,进行模块的加载。


2.接下来,我们来看一下Module.use方法

// Use function is equal to load a anonymous module load相当于执行一个匿名module
/**
 *开始整个加载流程,状态初始化为FETCHING到SAVED
 * @param ids 依赖模块
 * @param callback 模块id
 * @param uri 获取uri模块
 */
Module.use = function (ids, callback, uri) {
   
  var mod = Module.get(uri, isArray(ids) ? ids : [ids])

  mod._entry.push(mod)
  mod.history = {}
  mod.remain = 1 //未加载的模块个数

  mod.callback = function() {
   
    var exports = []
    var uris = mod.resolve()

    for (var i = 0, len = uris.length; i < len; i++) {
      exports[i] = cachedMods[uris[i]].exec()
    }

    if (callback) {
      callback.apply(global, exports)
    }

    delete mod
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值